How to specify a constructor with a functional component (fat arrow syntax)?

后端 未结 5 772
南笙
南笙 2020-12-15 16:46

Given this component:

import React from \'react\'
import ReactDOM from \'react-dom\'
import PropTypes from \'prop-types\'

const NewGoalInput = props => {         


        
5条回答
  •  一个人的身影
    2020-12-15 17:31

    Now that we have useState and hooks the answers are kind of out of date. I came across this question because I was doing something wrong. Here's some simplified code of what I was doing.

    // set an initial state
    const [ value, setValue ] = useState(0)
    
    // gets called after component is re-rendered
    useEffect(() => {
       // callback to parent that set props
       props.update()
    })
    
    // if we have an existing value passed in
    if (props.value) {
       setValue(props.value)
    }
    

    This code was converted from a stateful class to a function using hooks, originally setting the default props in the constructor - but functions don't have constructors and that check happens every time the component re-renders:

    1. calls useState
    2. triggers re-render
    3. useEffect is triggerd
    4. parent is called which sets the props
    5. props update so child renders again
    6. GOTO 1

    As you can see this results in an infinite loop. The solution is really quite simple. Here's a mock diff from the original.

    - const [ value, setValue ] = useState(0)
    + const [ value, setValue ] = useState(props.value || 0)
    
    - if (props.value) {
    -   setValue(props.value)
    - }
    

    Basically, just initialise the state from the props and don't do silly things like calling useState except in response to an event or callback of some type.

提交回复
热议问题