反应:用道具更改更新状态-handleChange和getDerivedStateFromProps

时间:2018-09-05 14:08:16

标签: reactjs state

我正在尝试使某些组件的数据输出取决于某些外部API。

所以我有这个片段:

class Parent extends Component {
    constructor(props) {
        super(props)

        this.state = {
            somethingFromAPI: ''
        }
    }

    componentDidMount() {
        /* 
            something on axios.get() which updates this.state.somethingFromAPI 
            which normally can have some time delay till executed
        */
    }

    render() {
        return (
            <Child value={this.state.somethingFromAPI} />
        )
    }
}

class Child extends Component {

    constructor(props) {
        super(props)

        this.state = {
            value: this.props.value || ''
        }
    }

    handleChange(event) {
        this.setState({
            value: event.target.value
        })
    }

    static getDerivedStateFromProps(props, state) {
        // if difference
        return {
            value: props.value
        }
    }

    render() {
        return (
            <div>
                <input value={this.state.value} onChange={this.handleChange.bind(this)} />
            </div>
        )
    }

}


ReactDOM.render(     
  <Parent />
  document.getElementById('app')        
);

看起来像这样工作正常,可以初始化组件并获取API数据,此后,输入值似乎已更新,这是我所期望的。

困扰我很多的问题是,如果我在输入中键入内容,这将调用handleChange,但还会触发此getDerivedStateFromProps并将新输入的值替换为API中的“旧”值。

这是这样做的好方法吗,也许我一开始就理解应该如何做就犯了错误?指引我正确的方向。

我还是React的新手。

通常,需要制作可用于新输入或更新现有数据(例如某些帖子等)的表格,以便我可以加载API数据。

最诚挚的问候。

2 个答案:

答案 0 :(得分:0)

我认为在这里使用getDerivedStateFromProps可能是不必要的。如果要在某些情况下阻止渲染,请考虑使用shouldComponentUpdate https://reactjs.org/docs/react-component.html#shouldcomponentupdate。但这听起来像您基本上只需要使用输入更改处理程序来保持输入的状态即可。

您还应该查看this文章,了解为什么不应该使用getDerivedStateFromProps。非常有用。

答案 1 :(得分:0)

如果使用shouldComponentUpdate,您是否考虑使用getDerivedStateFromProps

类似的事情可能会解决您的问题:

  shouldComponentUpdate(nextProps, nextState) {
    const { value: nextPropsValue } = nextProps;
    const { value: propsValue } = this.props;

    const { value } = this.state;

    if (nextPropsValue !== propsValue && nextPropsValue !== value) {
      this.setState({
        value: nextPropsValue
      });
    }

    return value !== nextState.value;
  }

更新答案并与当前道具值进行比较