Reactjs - 使用子组件中的setState从props设置State

时间:2017-05-04 09:47:16

标签: javascript reactjs react-native

我有以下类根据排序下拉列表呈现用户。如果我选择"字母顺序"用户将按字母顺序列出。当我选择" group"。

时,按小组顺序排列
render(){
    return(
        const {members, sort} = this.state
        { sort === "alphabetical" && <SortByAlphabet members={members} /> }
        { sort === "group" && <SortByGroup members={members}/> }
    )
)

<SortByAlphabet />组件中,我正在componentWillReceiveProps()函数中的props.members设置组件状态对象。

componentWillReceiveProps = props => {
    this.setState({ members : props.members });
}

当我选择&#34; group&#34; sort,<SortByAlphabet />组件正在卸载,<SortByGroup />正在DOM中安装。再次当我切换回&#34;按字母顺序排列&#34; sort,在<SortByAlphabet />组件中优先设置的状态变量(成员)变为NULL,因为组件已从DOM中删除。

当重新渲染componentWillReceiveProps时,

<SortByAlphabet />函数没有触发,因为道具没有改变。但我想更新状态变量,就像我第一次在componentWillReceiveProps函数中做的那样。

怎么做?

2 个答案:

答案 0 :(得分:6)

正如@Vikram所说,componentWillReceiveProps没有第一次被调用,所以当你的组件最初被挂载时你的状态没有被设置,所以你需要在{{1}中设置带状态的状态函数(仅在第一个渲染时调用)以及componentWillMount/componentDidMount函数

componentWillReceiveProps

版本16.3.0 开始,您将使用getDerivedStateFromProps方法更新状态以响应道具更改,

  在实例化组件后调用

componentWillReceiveProps = props => { if(props.members !== this.props.members) { this.setState({ members : props.members }); } } componentWillMount() { this.setState({ members : this.props.members }); }   以及当它收到新道具时。它应该返回一个对象   更新状态,或null以指示新道具不需要   任何州的更新。

getDerivedStateFromProps

修改 getDerivedStateFromProps API从v16.4发生了变化,它接收到props,state作为参数,并在每次更新时调用以及初始渲染。在这种情况下,您可以通过更改密钥

来触发组件的新安装
static getDerivedStateFromProps(nextProps, prevState) {
    if(nextProps.members !== prevState.memebers) {
         return { members: nextProps.members };
    }
    return null;
}

并且在SortByAlphabet中有

<SortByAlphabet  key={members} />

或使用像

这样的getDerivedStateFromProps
componentWillMount() {
     this.setState({ members : this.props.members });
}

答案 1 :(得分:5)

componentWillMount仅在组件生命周期中被调用一次,紧接在呈现组件之前。它通常用于执行初始渲染之前所需的任何状态更改,因为在此方法中调用this.setState不会触发其他渲染 所以你可以使用

更新你的staate
componentWillMount ()
{

        this.setState({ members : props.members });


}