如何在React中更新父级的状态?

我的结构如下所示:

组件1

  • | – 组件2

    • | – 组件4
      • | – 组件5

组件3

组件3应根据组件5的状态显示一些数据。由于道具是不可变的,我不能简单地将它保存在组件1中并转发它,对吗? 是的,我已经阅读了关于REDX,但不想使用它。 我希望能够通过反应来解决这个问题。 我错了吗?

最好的感谢,Wojtek

对于孩子父母的沟通,你应该通过一个函数来设置从父母到孩子的状态,像这样

class Parent extends React.Component { constructor(props) { super(props) this.handler = this.handler.bind(this) } handler(e) { e.preventDefault() this.setState({ someVar: someValue }) } render() { return <Child handler = {this.handler} /> } } class Child extends React.Component { render() { return <Button onClick = {this.props.handler}/ > } } 

我喜欢关于传递函数的答案,它是一个非常方便的技术。

另一方面,您也可以使用pub / sub或使用Flux的变体,调度程序来实现此function。 理论超级简单,有组件3正在监听的组件5调度消息。 组件3然后更新其触发重新呈现的状态。 这需要有状态的组件,根据你的观点,这可能是也可能不是反模式。 我个人反对他们,宁愿别的什么东西在倾听调度和改变状态从上到下(Redux做这个,但增加了额外的术语)。

 import { Dispatcher } from flux import { Component } from React const dispatcher = new Dispatcher() // Component 3 // Some methods, such as constructor, omitted for brevity class StatefulParent extends Component { state = { text: 'foo' } componentDidMount() { dispatcher.register( dispatch => { if ( dispatch.type === 'change' ) { this.setState({ text: 'bar' }) } } } render() { return <h1>{ this.state.text }</h1> } } // Click handler const onClick = event => { dispatcher.dispatch({ type: 'change' }) } // Component 5 in your example const StatelessChild = props => { return <button onClick={ onClick }>Click me</button> } 

与Flux捆绑在一起的调度程序非常简单,它只是简单地注册callback,并在调度发生时调用它们,通过调度内容(在上面简洁的例子中,调度没有payload ,只是一个消息ID)。 你可以很容易地适应这个传统的pub / sub(例如事件中使用EventEmitter,或其他版本),如果这对你更有意义。

我发现下面的工作解决scheme将从child传递的onClick函数parameter passing给父组件:

 //ChildB component class ChildB extends React.Component { render() { var handleToUpdate = this.props.handleToUpdate; return (<div><button onClick={() => handleToUpdate('someVar')}>Push me</button></div> ) } } //ParentA component class ParentA extends React.Component { constructor(props) { super(props); var handleToUpdate = this.handleToUpdate.bind(this); var arg1 = ''; } handleToUpdate(someArg){ alert('We pass argument from Child to Parent: ' + someArg); this.setState({arg1:someArg}); } render() { var handleToUpdate = this.handleToUpdate; return (<div> <ChildB handleToUpdate = {handleToUpdate.bind(this)} /></div>) } } if(document.querySelector("#demo")){ ReactDOM.render( <ParentA />, document.querySelector("#demo") ); } 

看看JSFIDDLE

当您需要在任何级别的孩子与家长之间进行沟通时,最好使用上下文 。 在父组件中定义可以由孩子调用的上下文,如

在您的案例组件3中的父组件

  static childContextTypes = { parentMethod: React.PropTypes.func.isRequired }; getChildContext() { return { parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child) }; } parentMethod(parameter_from_child){ // update the state with parameter_from_child } 

现在在子组件(在你的情况下是组件5),只要告诉这个组件,它想要使用其父母的上下文。

  static contextTypes = { parentMethod: React.PropTypes.func.isRequired }; render(){ return( <TouchableHighlight onPress={() =>this.context.parentMethod(new_state_value)} underlayColor='gray' > <Text> update state in parent component </Text> </TouchableHighlight> )} 

你可以在回购中findDemo项目

我发现下面的工作解决scheme,以传递onClick函数参数从子项到父组件与param:

父类:

 class Parent extends React.Component { constructor(props) { super(props) // Bind the this context to the handler function this.handler = this.handler.bind(this); // Set some state this.state = { messageShown: false }; } // This method will be sent to the child component handler(param1) { console.log(param1); this.setState({ messageShown: true }); } // Render the child component and set the action property with the handler as value render() { return <Child action={this.handler} /> }} 

小孩class:

 class Child extends React.Component { render() { return ( <div> {/* The button will execute the handler function set by the parent component */} <Button onClick={this.props.action.bind(this,param1)} /> </div> ) } } 
Interesting Posts