Tushar Sharma
Tushar Sharma

Reputation: 31

What is solution for constructor in functional components in react native?

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

Answers (3)

SGX
SGX

Reputation: 3353

People suggested useEffect but it will be invoked after render.

Use useMemo instead:

useMemo(() => {
  console.log('This is useMemo')
}, []);

Upvotes: 0

Mik378
Mik378

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

R Pasha
R Pasha

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

Related Questions