Reputation: 31
Let me take you to my problem. I am making a timer functional component, I am passing startValue to component and then that component will start timer(decreasing one in second) using startValue passed through props.
const FunctionalComponent = (props: any) => {
const [timerValue, setTimerValue] = useState(props.initialValue)
console.log('Set State')
useEffect(() => {
console.log('UseEffects called')
setInterval(() => {
setTimerValue(timerValue - 1)
}, 1000)
}, [])
return <View><Text style={styles.textStyle}>{timerValue}</Text></View>
}
My render function in Parent.
render() {
return <View style={styles.mainView}>
<FunctionalComponent initialValue={30} />
</View>
}
Now, Every time react re-render parent component, FunctionalComponent gets called and resets timerValue value. I solved this problem using class component constructor, but I wonder is there any solution to do same in functional components.
class OTPTimer extends Component {
constructor(props: any) {
super(props)
this.state = {
timeLeft: props.fromStart
}
if (props.startTimer) {
this.startTimer()
}
}
componentDidUpdate(prevProps: any) {
if (!prevProps.startTimer && this.props.startTimer) {
this.startTimer()
this.setState({
timeLeft: this.props.fromStart
})
}
}
startTimer = () => {
var interval = setInterval(() => {
this.setState({
timeLeft: this.state.timeLeft - 1
})
if (this.state.timeLeft === 0) {
clearInterval(interval)
}
}, 1000)
}
render() {
return <Text style={globalStyles.testStyleThree}>{`00:${this.state.timeLeft > 9 ? this.state.timeLeft : `0${this.state.timeLeft}`}`}</Text>
}
}
Upvotes: 3
Views: 1894
Reputation: 3353
People suggested useEffect
but it will be invoked after render.
Use useMemo
instead:
useMemo(() => {
console.log('This is useMemo')
}, []);
Upvotes: 0
Reputation: 22171
This is where it makes sense to use React.memo in order to prevent re-rendering child components when their props don't change.
React.memo is a higher order component. It’s similar to React.PureComponent but for function components instead of classes.
If your function component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.
const FunctionalComponent = React.memo<{initialValue: number}>({initialValue}) => {
const [timerValue, setTimerValue] = useState(initialValue)
console.log('Set State')
useEffect(() => {
console.log('UseEffects called')
setInterval(() => {
setTimerValue(timerValue - 1)
}, 1000)
}, [])
return <View><Text style={styles.textStyle}>{timerValue}
</Text></View>
};
Upvotes: 1
Reputation: 700
checkout React.memo, witch will prevent child component to re-render if it's props has not changed
const FunctionalComponent = React.memo((props: any) => { .... } )
Upvotes: 1