Converting componentWillReceiveProps - react-native

componentWillReceiveProps(nextProps) {
if (this.props.active !== nextProps.active) {
Animated.timing(this._active, {
duration: 300,
easing: Easing.bounce,
toValue: Number(nextProps.active),
}).start();
}
}
This is the code of react-native-sortable-list.
And what I am trying to do is change this code with react-hook
Is there any help can I get to change componentWillReceiveProps part to functional component?

You can use useEffect with dependency list. when props.active changes component will rerender
useEffect(()=>{
Animated.timing(props.active, {
duration: 300,
easing: Easing.bounce,
toValue: Number(props.active),
}).start();
},[props.active])

Related

React Native Animation Boomerang style

I am trying to create a red led "Recording Like" element. I'd like to see it blinking smoothly.
useEffect(() => {
Animated.loop(
Animated.timing(
fadeAnim,
{
toValue: 0,
duration: 1000
}
).start(() =>{
Animated.timing(
fadeAnim,
{
toValue: 1,
duration: 1000
}
).start();
})
).start();
}, [fadeAnim])
<Animated.View style={[styles.recordingLed, {opacity: fadeAnim}]} />
It actually goes to 0, then to 1 and then stop. I need something continuos, endless. Any clue ?
You need to add some Easing (https://reactnative.dev/docs/easing) to your animation run smoothly, example:
const fadeAnim = new Animated.Value(0);
useEffect(() => {
Animated.loop(
Animated.timing(fadeAnim, {
toValue: 1,
duration: 1000,
easing: Easing.bezier(0.645, 0.045, 0.355, 1.0),
useNativeDriver: true,
}),
).start();
}, [fadeAnim]);
<Animated.View style={[styles.recordingLed, {opacity: fadeAnim}]} />
Also you can check this:
Maybe some pre made animations from can help you https://github.com/oblador/react-native-animatable#animations-2 ? Remember to mark the looping flag (https://github.com/oblador/react-native-animatable#looping)

React native animation is no working with setState function

I have this function:
const moveSwitch = () => {
setLeftStatus(!leftStatus);
Animated.timing(xValue, {
toValue: leftStatus ? 0 : 26,
duration: 300,
easing: Easing.linear,
useNativeDriver: false,
}).start();
};
It works if I remove the conditional option and setState.
Any suggestions please?
If anyone comes around this problem here is how I solved it.
Since setState function re-renders component animation was not working.
So I just created ref using useRef and updated it like this:
const moveSwitch = () => {
Animated.timing(xValue, {
toValue: leftStatus.current ? 0 : 26,
duration: 300,
easing: Easing.linear,
useNativeDriver: false,
}).start(event => {
if (event.finished) {
if (leftStatus.current) {
return (leftStatus.current = false);
} else {
return (leftStatus.current = true);
}
}
});
};

How to remove latency of UI when setting state of big array in React Native?

I am using React Native to render a Chart.
I have 3 custom tabs in my app, when sliding between them I am getting new data and apply translation animation to highlight the selected tab.
I am facing a 1 second latency when scrolling. I investigated the latency and there is one parameter in setState() that is causing it, which is a big array of data.
I am already using async / await.
I tried to put setState() inside a setTimeout but the final result isn't smooth.
Is there a way to optimize setting big array in the state ? Or play the animation inpendently from setState() ?
Update
await Animated.spring(translateBottomX, {
toValue: type,
duration: 100,
}).start();
if (segment === 1) {
await Animated.parallel([
Animated.spring(translateXBottomTabOne, {
toValue: 0,
duration: 100,
}).start(),
Animated.spring(translateXBottomTabTwo, {
toValue: width,
duration: 100,
}).start(),
]);
} else if (segment === 2) {
await Animated.parallel([
Animated.spring(translateXBottomTabOne, {
toValue: width,
duration: 100,
}).start(),
Animated.spring(translateXBottomTabTwo, {
toValue: 0,
duration: 100,
}).start(),
]);
} else if (segment === 3) {
await Animated.parallel([
Animated.spring(translateXBottomTabOne, {
toValue: width,
duration: 0,
}).start(),
Animated.spring(translateXBottomTabTwo, {
toValue: width,
duration: 100,
}).start(),
]);
}
setTimeout(() => {
this.setState({
dataAxeX
});
}, 500);
// using it here
<XAxis
data={dataAxeX}
formatLabel={(_, index) => dataAxeX[index].Datetime}
contentInset={styles.xAxisContentInset}
svg={{
fill: "#B6C1DF",
...styles.xAxisStyle,
}}
/>

multiple react native animations with reanimated base on a state?

I am new to react native animations and I am specifically using react native reanimated, this is my code old code which is used in text input, I am changing the fontsize and translate Y of a label:
const labelSize = new Animated.Value(14);
const translateY = new Animated.Value(0);
const onFocus = () => {
setHasFocused(true);
Animated.timing(labelSize, {
toValue: 11,
duration: 250,
easing: Easing.in(Easing.ease),
}).start();
Animated.timing(top, {
toValue: -14,
duration: 250,
easing: Easing.in(Easing.ease),
}).start();
};
const onBlur = () => {
setHasFocused(false);
Animated.timing(labelSize, {
toValue: 14,
duration: 250,
easing: Easing.out(Easing.ease),
}).start();
Animated.timing(top, {
toValue: 0,
duration: 250,
easing: Easing.in(Easing.ease),
}).start();
};
however it doesn't seem to feel right, I've researched and resulted to this, I believe I have to use clock and timing with this, which I find hard and can't make to work, what I want to do is something like this:
const clock = new Clock();
useCode(
() => [
set(isPlaying, hasFocused ? 1 : 0),
set(translateY, hasFocused ? 1 : 0),
],
[hasFocused]
);
now I believe with timing I have to use clock with it:
const state = {
finished: new Animated.Value(0),
position: new Animated.Value(0),
frameTime: new Animated.Value(0),
time: new Animated.Value(0),
};
const config = {
toValue: new Animated.Value(1),
duration: 3000,
easing: Easing.inOut(Easing.ease),
};
timing(clock, state, config)
what I simply want to do is update animation values based if the input is focused and not, help?

React native animation is not working for the second time

I have used the default "Animated" package with react native for my animations in the application. Animations in the following code is working fine. But when I navigate to another page and come back to this screen the animation is not working. Once the page gets loaded from ground level only it is working again. What could be the reason ? Can someone please help me to sort this out.
class LoginScreen extends Component {
static navigationOptions = {
header: null
}
state = {
username: '',
password: '',
animation: {
usernamePostionLeft: new Animated.Value(795),
passwordPositionLeft: new Animated.Value(905),
loginPositionTop: new Animated.Value(1402),
statusPositionTop: new Animated.Value(1542)
}
}
navigateToScreen = link => event => {
this.props.navigation.navigate(link)
}
componentDidMount() {
const timing = Animated.timing
Animated.parallel([
timing(this.state.animation.usernamePostionLeft, {
toValue: 0,
duration: 1700
}),
timing(this.state.animation.passwordPositionLeft, {
toValue: 0,
duration: 900
}),
timing(this.state.animation.loginPositionTop, {
toValue: 0,
duration: 700
}),
timing(this.state.animation.statusPositionTop, {
toValue: 0,
duration: 700
})
]).start()
}
render() {
return (
<View style={styles.container}>
<ImageBackground
source={lem_bg}
blurRadius={10}
style={styles.imageBgContainer}>
<View style={styles.internalContainer}>
<Animated.View style={{position: 'relative', top:
this.state.animation.usernamePostionLeft, width: '100%'}}>
<Text style={styles.LEMHeader}>LEM<Text style={styles.followingtext}>mobile</Text></Text>
</Animated.View>
</ImageBackground>
</View>
....MORE JSX ARE THERE...
)
}
}
componentDidMount() won't call when you navigate back from another screen. for this, you have to create your own callback method for performing this animation when you pop() from another screen. Consider below code change
first screen
navigateToScreen = link => event => {
this.props.navigation.navigate(link,{
callback:this.runAnimation
})
}
componentDidMount() {
this.runAnimation()
}
runAnimation(){
const timing = Animated.timing
Animated.parallel([
timing(this.state.animation.usernamePostionLeft, {
toValue: 0,
duration: 1700
}),
timing(this.state.animation.passwordPositionLeft, {
toValue: 0,
duration: 900
}),
timing(this.state.animation.loginPositionTop, {
toValue: 0,
duration: 700
}),
timing(this.state.animation.statusPositionTop, {
toValue: 0,
duration: 700
})
]).start()
}
on the second screen when you pop() navigation to back, call this callback
this.props.navigator.pop()
this.props.callback()