我的结构如下所示:

Component 1

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5

Component 3

组件3应该根据组件5的状态显示一些数据。

因为道具是不可变的,我不能简单地在组件1中保存它的状态并转发它,对吗?是的,我读过Redux,但我不想使用它。我希望只用react就能解决这个问题。我错了吗?


当前回答

父组件

 function Parent() {
        const [value, setValue] = React.useState("");

        function handleChange(newValue) {
          setValue(newValue);
        }

        // We pass a callback to Child
        return <Child value={value} onChange={handleChange} />;
    }

子组件

    function Child(props) {
         function handleChange(event) {
             // Here, we invoke the callback with the new value
             props.onChange(event.target.value);
         }
  
         return <input value={props.value} onChange={handleChange} />
    }

其他回答

当您需要在子节点和父节点之间进行任何级别的通信时,最好利用上下文。在父组件中定义可以被子组件调用的上下文,例如:

在父组件中,在你的案例中,组件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>
)}

您可以在这个GitHub存储库中找到Demo项目。

对于子-父通信,您应该传递一个函数来设置从父到子的状态,如下所示


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

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      someVar: 'some value'
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {this.props.handler}/ >
  }
}

这样,子进程就可以通过调用带有props的函数来更新父进程的状态。

但是你必须重新考虑组件的结构,因为根据我的理解,组件5和组件3是不相关的。

一种可能的解决方案是将它们包装在一个更高级别的组件中,该组件将同时包含组件1和组件3的状态。该组件将通过props设置较低级别的状态。

下面是获得两种绑定数据方式的简短代码片段。

计数器显示来自父进程的值,并从子进程更新

class Parent extends React.Component { constructor(props) { super(props) this.handler = this.handler.bind(this) this.state = { count: 0 } } handler() { this.setState({ count: this.state.count + 1 }) } render() { return <Child handler={this.handler} count={this.state.count} /> } } class Child extends React.Component { render() { return <button onClick={this.props.handler}>Count {this.props.count}</button> } } ReactDOM.render(<Parent />, document.getElementById("root")); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

这似乎对我有用

家长:

...

const [open, setOpen] = React.useState(false);

const handleDrawerClose = () => {
    setOpen(false);
  };

...

return (
                <PrimaryNavigationAccordion           
                  handleDrawerClose={handleDrawerClose}               
                />
              );

孩子:

...

export default function PrimaryNavigationAccordion({
  props,
  handleDrawerClose,
})

...

<Link
                    to={menuItem.url}
                    component={RouterLink}
                    color="inherit"
                    underline="hover"
                    onClick={() => handleDrawerClose()}
                  >
                    {menuItem.label}
                  </Link>

如果你想要更新父组件,

class ParentComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = {
           page: 0
        }
    }

    handler(val){
        console.log(val) // 1
    }

    render(){
        return (
            <ChildComponent onChange={this.handler} />
        )
    }
}


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page: 1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
            <Button
                onClick={() => this.someMethod()}
            > Click
        </Button>
      )
   }
}

这里的onChange是一个带有“handler”方法绑定到其实例的属性。我们将方法处理程序传递给子类组件,通过props参数中的onChange属性接收。

onChange属性将在props对象中设置,如下所示:

props = {
    onChange: this.handler
}

并传递给子组件。

所以子组件可以像props. onchange这样访问props对象中的name值。

这是通过使用渲染道具完成的。

现在子组件有一个按钮“Click”,带有一个onclick事件集,用于调用通过props参数对象中的onChange传递给它的处理程序方法。所以现在子类中的this.props.onChange保存了父类中的输出方法。

参考资料和演职员表:Bits and Pieces