Crash React Native useAnimatedKeyboard() - react-native

Hello I'm trying to use useAnimatedKayboard() hook from reanimated 2, everything works fine until I click r to reload the project. The app crashes in android and in ios. I'm using it exactly the same as the doc:
function AnimatedKeyboardExample() {
const keyboard = useAnimatedKeyboard();
const translateStyle = useAnimatedStyle(() => {
return {
transform: [{ translateY: -keyboard.height.value }],
};
});
return (
<ScrollView contentContainerStyle={{flex: 1, justifyContent: 'center',
alignItems: 'center' }}>
<Animated.View style={translateStyle}>
<TextInput />
</Animated.View>
</ScrollView>
);
}
Does anyone know how to resolve this?
EDIT: this is a new project in Expo

useAnimatedKeyboard is a Reanimated 3 feature, you're using Reanimated 2, which doesn't have it. The app crashes are most likely from calling the undefined function. If you can upgrade to Reanimated 3, that's probably your quickest solution.
The docs you linked aren't super obvious about it, but they are from the "next" version, which is 3.0. If you click through to the docs from the current release, you'll see it's not in the Hooks section.

Related

React Native Gesture Handler Not Working On Android

I am using react-native-gesture-handler and react-native-reanimated package to animate a View in react native. The scale of the view should increase on tap and the backgroundColor should change to red on tap. Everything works fine when I launch the app on the web but on android I
get no feedback. I used snack to text my code on my device and that worked on my android device but when I run the project with expo-start on my laptop the gesture handling doesn't work at all. Any help will be much appreciated 🙏🙏🙏🙏. The project is expo managed.
I am using react-native-reanimated version "~2.3.1", react-native-gesture-handler version "2.1.0";
//MY APP.JS FILE
import "react-native-gesture-handler";
import { StyleSheet, Text, View } from "react-native";
import Animated,{useAnimatedGestureHandler, useAnimatedStyle, useSharedValue} from "react-native-reanimated";
import { TapGestureHandler } from "react-native-gesture-handler";
export default function App() {
const pressed= useSharedValue(false);
const gestureEvent= useAnimatedGestureHandler({
onStart:()=>{
pressed.value=true
},
onActive:(e)=>{
pressed.value=true;
},
onEnd:()=>{
pressed.value=false;
}
});
const animationStyle=useAnimatedStyle(()=>{
return {
transform:[{scale:pressed.value?1.3:1}],
backgroundColor:pressed.value?"red":"yellow"
}
})
return (
<View style={styles.container}>
<TapGestureHandler onGestureEvent={gestureEvent} >
<Animated.View style={[styles.view,animationStyle]}></Animated.View>
</TapGestureHandler>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
view:{
backgroundColor:"blue",
width:100,
height:100,
borderRadius:20,
}
});
// BABEL CONFIG.JS
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: ["react-native-reanimated/plugin"],
};
};
The scale of the view should increase on tap and the backgroundColor should change to red on tap. Everything works fine when I launch the app on the web but on android I
get no feedback. I used snack to text my code on my device and that worked on my android device but when I run the project with expo-start on my laptop the gesture handling doesn't work at all.
Is <GestureHandlerRootView> somewhere in your hierarchy? I've noticed this is not required in iOS, but is in Android. See their Docs.
Wrap your entire app with
<GestureHandlerRootView style={{flex: 1}}>
</GestureHandlerRootView>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
The Flex: 1 is important, without it your app won't be able to detect gestures on android.

React-native Display of AutoHeightWebView causes crash in Android 10 and Android 11

I seldom ask a question but want to see whether someone has a similar experience.
In coding a react-native app, I've included the component AutoHeightWebView on a page (together with other components, such as text and images.)
A strange behaviour occurs is that when the app is installed in physical devices:
For devices of Android 9 and below: normal
For devices of Android 10 and 11: app will crash when this page is displayed (say navigated from another page)
The following is extract of the code
import React, {Component} from 'react';
import AutoHeightWebView from 'react-native-autoheight-webview'
import { Dimensions } from 'react-native'
// other imports
export default class NdetailScreen extends Component {
render(){
return (
<View style={{ flex: 1, alignItems: 'center' }}>
<ScrollView style={{flex:1}}>
<Image
resizeMode={'contain'}
style={{ width: '100%', height: 200 }}
source={{uri: this.state.homepic}}
/>
<AutoHeightWebView
style={{ width: Dimensions.get('window').width , marginTop: 0 }}
source={{ uri: 'https://xxxxxx.com/nshow.php?serial=' + this.props.route.params.unitserial + '&lang=' + this.props.route.params.lang }}
scalesPageToFit={false}
viewportContent={'width=device-width, user-scalable=no'}
/>
<View style={{height:80}}><Text> ... other text </Text></View>
</ScrollView>
</View>
)
}
}
The strange thing is, if I remove the following block, everything works fine (in the Android 10 and 11 smartphones):
<AutoHeightWebView
style={{ width: Dimensions.get('window').width , marginTop: 0 }}
source={{ uri: 'https://xxxxxx.com/nshow.php?serial=' + this.props.route.params.unitserial + '&lang=' + this.props.route.params.lang }}
scalesPageToFit={false}
viewportContent={'width=device-width, user-scalable=no'}
/>
Any advice ?
I believe it is a bug of AutoHeightWebView (because I have already used the most up-dated version of AutoHeightWebView and my expo / npm versions are all up-to-date.
After repeatedly observing the "crash" behaviour, I have found that if I've removed the AutoHeightWebView part, there will NOT be any crash. So it can be run without problem in an Android 10/11 devices. After that if I re-added the AutoHeightWebView part -- there will be no crash ! (you know it can be done by real-time updating of code when the device is connected to the expo development platform)
So if the AutoHeightWebView part is already there while I navigate to the screen, it will crash in the Android 10/11 devices, but if it is "added" LATER, it will be fine.
Hence, I have used a trick to fix the problem.
change the code so that the AutoHeightWebView part will NOT be rendered when the page is first loaded
in the componentDidMount() part, add a setTimeout function (say 0.5 second) to change a control state so that the AutoHeightWebView will be rendered again after 0.5 seconds when the page is loaded
The following is the code
constructor() {
super();
this.state={xxtime4:0}
}
componentDidMount() {
setTimeout(() => {
this.setState({xxtime4:'10'});
}, 500);
}
kenlist3() {
if (this.state.xxtime4==0) {
return null
} else {
return (
<AutoHeightWebView
style={{ width: Dimensions.get('window').width , marginTop: 0 }}
source={{ uri: 'https://www.xxxxx.com/displaytext.php' }}
scalesPageToFit={false}
viewportContent={'width=device-width, user-scalable=no'}
/>
)
} }
In this way, if I use {this.kenlist3()}, it will be able to display the AutoView in all the physical devices. (including Android 10/11).
I just hope that in future this bug will be fixed by the developer so that I do not need to use such a "trick". But at least it is fine for the time being.
Hope that the above can also help someone.

How to access params passed to a class based component in react navigation 5.0?

Using react-navigation you can pass parameters like this:
this.props.navigation.navigate(screen, {param: value});
and in previous versions you could access the parameters like this:
props.navigation.state.params
In the new version of react-navigation (5.0) they use functional components, and it appears you cannot access the params as you did before. Instead, you write components and access params like this:
function HomeScreen({ navigation, route }) {
React.useEffect(() => {
if (route.params?.post) {
// Post updated, do something with `route.params.post`
// For example, send the post to the server
}
}, [route.params?.post]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Create post"
onPress={() => navigation.navigate('CreatePost')}
/>
<Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>
</View>
);
}
How can I access the parameters passed to a component, without having to change all of the components in a project from class-based to functional-based components?
You just have change the code you used to access params from
props.navigation.state.params
to
props.route.params
All will be good no need to change class-based to functional-based components.
But i will suggest you start migrating at your own ease so you code will be as per the latest syntax.
You can see an example of this with the snippet here on this Expo snack
here on this Expo snack

How to modify expo android styles.xml in react native app

As many others before me, I'm looking for the way to customize expo android's theme colors and styles in order to customize native components styles like DatePicker.
I found a lot of posts explaining the same old thing: "Update your style the native android way!"
Ok then, but my React native project doesn't have any "res/values/styles.xml" and so on. Creating them from scratch has no effect.
There's one step that I'm deadly missing here, but which one?
My repo looks a bit like this actually:
.expo
/* a bunch of folders containing my custom js */
App.js
app.json
babel.config.js
package.json
package-lock.json
You can use Style Sheet.
Create a new StyleSheet:
const styles = StyleSheet.create({
container: {
borderRadius: 4,
borderWidth: 0.5,
borderColor: '#d6d7da',
},
title: {
fontSize: 19,
fontWeight: 'bold',
},
activeTitle: {
color: 'red',
},
});
Use a StyleSheet:
<View style={styles.container}>
<Text style={[styles.title, this.props.isActive && styles.activeTitle]} />
</View>
this is detail link
To configure a style, such as Android.xml, you can separate it by doing expo eject.
When you do expo eject, you get Android folder.
about `expo eject' link

SegmentedControlIOS for android in react-native

I am confused with the usage of SegmentedControlIOS in react-native, i check it in IOS simulator it works, But when i check it in android it throws an error as below
SegmentedControlIOS is not supported on this platform
here is my code:
<View >
<SegmentedControlIOS
tintColor="#D7D7D5"
style={styles.SegmentedControlIOS}
values={this.state.values}
selectedIndex={this.state.selectedIndex}
onChange={this._onChange}
onValueChange={(val) =>{
this.setState({
value:val
})
}}/>
</View>
Can anyone give me suggestions on how to use SegmentedControlIOS for both android and IOS, Any help in this regard is much appreciated.
SegmentedControl is a built in native component on iOS. However, there is no direct equivalent on Android which is why the react native component name ends with IOS and isn't support on Android. There is no obvious way make the built in component work on Android.
That leaves you with two options:
Use or create your own version using standard components. This library has a good approximation of a segmented control that would work on both operating systems.
Use two separate components on iOS and Android which can be done automatically by creating two files named:componentName.android.js and componentName.ios.js (See here for more information using different code for each platform).
The iOS specific code could use the iOS segmented control and the Android version could use something like https://github.com/zzyyppqq/react-native-segmented-android or a custom implementation.
See react-native-segmented-control-tab
for similar usage between both platform:
__
-
or
see ButtonGroup from react-native-elements
https://react-native-training.github.io/react-native-elements/docs/button_group.html
Very simple component, 100% compatible with IOS version.
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var { Component, View, Text, TouchableOpacity } = ReactNative;
var SimpleSegmentedControl = React.createClass({
getInitialState: function () {
return {
values: this.props.values || [],
selectedIndex: this.props.selectedIndex || 0,
style: this.props.style || {},
onChange: this.props.onChange
};
},
componentWillReceiveProps: function (props) {
this.setState(props);
},
onPress: function (selectedIndex) {
if (typeof this.state.onChange === 'function') {
return this.state.onChange(selectedIndex);
}
},
render: function () {
return (
<View style={[{flexDirection: 'row', borderWidth: 1, borderColor: '#007AFF', borderRadius: 5}, this.state.style]}>
{this.state.values.map(function (value, position, values) {
return (
<TouchableOpacity key={position} onPress={()=>this.onPress(position)} style={{flex: 1}}>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', padding: 5,
backgroundColor: this.state.selectedIndex == position ? '#007AFF' : 'transparent',
borderRightWidth: position < values.length - 1 ? 1 : 0, borderRightColor: '#007AFF'}}>
<Text style={{fontSize: 13, color: this.state.selectedIndex == position ? 'white' : '#007AFF'}}>{value}</Text>
</View>
</TouchableOpacity>
);
}.bind(this))}
</View>
);
}
});
module.exports = SimpleSegmentedControl;
A good equivalent for SegmentedControlIOS should be Swipe Views with tab views:
https://developer.android.com/training/implementing-navigation/lateral.html
To use it in React Native android version you can use this library: https://github.com/skv-headless/react-native-scrollable-tab-view
It's strange that React Native's team not purpose this native component built in framework