Updating state on props change in React Form

前端 未结 11 1954
时光说笑
时光说笑 2020-12-02 04:15

I am having trouble with a React form and managing the state properly. I have a time input field in a form (in a modal). The initial value is set as a state variable in

相关标签:
11条回答
  • 2020-12-02 04:55

    The new hooks way of doing this is to use useEffect instead of componentWillReceiveProps the old way:

    componentWillReceiveProps(nextProps) {
      // You don't have to do this check first, but it can help prevent an unneeded render
      if (nextProps.startTime !== this.state.startTime) {
        this.setState({ startTime: nextProps.startTime });
      }
    }
    

    becomes the following in a functional hooks driven component:

    // store the startTime prop in local state
    const [startTime, setStartTime] = useState(props.startTime)
    // 
    useEffect(() => {
      if (props.startTime !== startTime) {
        setStartTime(props.startTime);
      }
    }, [props.startTime]);
    

    we set the state using setState, using useEffect we check for changes to the specified prop, and take the action to update the state on change of the prop.

    0 讨论(0)
  • 2020-12-02 04:56
    // store the startTime prop in local state
    const [startTime, setStartTime] = useState(props.startTime)
    // 
    useEffect(() => {
      if (props.startTime !== startTime) {
        setStartTime(props.startTime);
      }
    }, [props.startTime]);
    

    Can this method be migrated to class components?

    0 讨论(0)
  • 2020-12-02 05:02

    You Probably Don't Need Derived State

    1. Set a key from the parent

    When a key changes, React will create a new component instance rather than update the current one. Keys are usually used for dynamic lists but are also useful here.

    2. Use getDerivedStateFromProps / componentWillReceiveProps

    If key doesn’t work for some reason (perhaps the component is very expensive to initialize)

    By using getDerivedStateFromProps you can reset any part of state but it seems a little buggy at this time (v16.7)!, see the link above for the usage

    0 讨论(0)
  • 2020-12-02 05:02

    It's quite clearly from their docs:

    If you used componentWillReceiveProps for re-computing some data only when a prop changes, use a memoization helper instead.
    

    Use: https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#what-about-memoization

    0 讨论(0)
  • 2020-12-02 05:07

    componentWillReceiveProps is being deprecated because using it "often leads to bugs and inconsistencies".

    If something changes from the outside, consider resetting the child component entirely with key.

    Providing a key prop to the child component makes sure that whenever the value of key changes from the outside, this component is re-rendered. E.g.,

    <EmailInput
      defaultEmail={this.props.user.email}
      key={this.props.user.id}
    />
    

    On its performance:

    While this may sound slow, the performance difference is usually insignificant. Using a key can even be faster if the components have heavy logic that runs on updates since diffing gets bypassed for that subtree.

    0 讨论(0)
  • 2020-12-02 05:11

    componentWillReceiveProps is depcricated since react 16: use getDerivedStateFromProps instead

    If I understand correctly, you have a parent component that is passing start_time down to the ModalBody component which assigns it to its own state? And you want to update that time from the parent, not a child component.

    React has some tips on dealing with this scenario. (Note, this is an old article that has since been removed from the web. Here's a link to the current doc on component props).

    Using props to generate state in getInitialState often leads to duplication of "source of truth", i.e. where the real data is. This is because getInitialState is only invoked when the component is first created.

    Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.

    Basically, whenever you assign parent's props to a child's state the render method isn't always called on prop update. You have to invoke it manually, using the componentWillReceiveProps method.

    componentWillReceiveProps(nextProps) {
      // You don't have to do this check first, but it can help prevent an unneeded render
      if (nextProps.startTime !== this.state.startTime) {
        this.setState({ startTime: nextProps.startTime });
      }
    }
    
    0 讨论(0)
提交回复
热议问题