繁体   English   中英

ReactJS:通过props从父项中改变子状态

[英]ReactJS: Mutating child state from parent via props

免责声明:我看过Reactjs:如何从父级修改子状态或道具? 并且不相信答案符合我的问题。

因此,我有一个可重用的有状态会话组件,该组件根据其状态呈现不同的DOM。 我还必须能够控制从父级渲染哪个DOM。

TL; DR-我应该如何从父项中更改子组件状态,如果有的话,还有哪些其他选择?

孩子:

 export default class Conversation extends Component { constructor(props) { super(props); this.state = { newConversation: props.showNewConversation }; } render() { if (!this.state.newConversation) { return ( <div>Current Conversation</div> ); } return ( <div>New Conversation</div> ); } } 

现在,我需要在各个位置渲染此组件,但是我需要根据父对象渲染适当的DOM,即从导航栏可以创建新的对话,从用户页面可以直接进入与他们的对话,这样我就可以控制何时通过道具呼叫孩子。

通过prop调用child并设置状态:

 <Conversation showNewConversation={this.state.isConversationShown === true} /> 

这目前正在起作用,但是有人告诉我这在React中是一种非常不好的做法,我的问题实际上是为什么将其视为不好的做法,以及好的做法的解决方案会是什么样子。

在React中,一般的最佳实践是使尽可能多的组件处于“无状态”状态。 通常,如果您不加载异步数据或接受用户输入,则不需要状态。

在此示例中,主要问题发生如下:如果父级渲染

<Conversation newConversation={true} />

然后将其转交给

<Conversation newConversation={false} />

然后,子对象将无法像预期的那样进行渲染,因为React将“更新”子会话(重新渲染),但不会再次调用构造函数。 因为您仅将道具转移到构造函数中的状态,所以子对象永远不会改变。

而是大多数组件应仅根据其属性进行渲染。 您的孩子可以适应以下条件:

export default class Conversation extends Component {
  constructor(props) {
    super(props);
  }

  render() {
   if (!this.props.newConversation) {
    return (
      <div>Current Conversation</div>
    );
   } return (
      <div>New Conversation</div>
    );
  }
}

在此,父级进行的更新将允许子级正确地重新渲染,因为您直接在子级的render()函数中引用了props。

如果您有有关正在渲染的对话的更多数据,则应将所有数据作为道具传递。

<Conversation conversationData={{name: 'abc', new: false}} />

然后,对话组件可以直接在render()方法中访问道具。

如果您绝对必须更改状态,则应采用父母更改道具的形式:

export default class Conversation extends Component {
  constructor(props) {
    super(props);

    this.state = {
      newConversation: props.showNewConversation
    };
  }

  // Response to change
  componentWillReceiveProps(nextProps){
      this.setState({newConversation: this.props.showNewConversation});

  }

  render() {
   if (!this.state.newConversation) {
    return (
      <div>Current Conversation</div>
    );
   } return (
      <div>New Conversation</div>
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM