【问题标题】:How do I change this.state of a component from parent?如何从父级更改组件的 this.state?
【发布时间】:2019-10-29 08:22:57
【问题描述】:

我知道,在 ReactJS 中我可以将状态传递给组件。

父 jsx:

<Display active={this.state.dispActive} />

并像这样在子 jsx 渲染中使用它(示例):

<div>Display: {this.props.active ? 'Active' : 'Inactive'}</div>

但是当我尝试在孩子自己的状态下使用它时,它不起作用:

state = {
    isActive: this.props.active
}

可能状态在构造函数中被初始化一次,然后就没有改变了。

我想在这里调用一个函数,在孩子中,当道具的状态发生变化时。我发现解决这个问题的唯一方法是将所有子代码包含到父代码中,然后作为代码的结果传递状态

家长:

handleDisplayChange = (e) => {
    //Code here then use this.setState to change parent's this.state 
    //which then reflects on the passed props in the child
}

但是,如果子对象包含某种逻辑上不属于父对象的库,我想说设置该对象的某个属性在子对象中

this.display = new Display();
this.display.setActive = this.state.isActive

this.display 是在子级中构造的。它不属于父母的上下文。我需要

  1. 设置 this.display.setActive 的子函数
  2. 设置子本身的 this.state.isActive。

这不属于 Parent.jsx,因为 parent 应该将显示放置在一个 jsx 构造函数中,而将按钮工具栏放置在另一个中:

<div className="App">
    <Toggle toggleState={this.toggleState} active={this.state.dispActive}/>
    <Display active={this.state.dispActive} />
</div>

编辑:粘贴了错误的代码,进行了编辑以使其更有意义。

【问题讨论】:

  • 你可以使用componentDidUpdate()来检测变化
  • @ShoebMirza 我试过这个,但它不起作用。事实上它有效,但总是为时已晚。 ReactJS 似乎更新了孩子的 jsx,然后运行 ​​did update 来改变状态。我单击切换,显示显示“活动”,但孩子中的 this.state.isActive 仍然显示为 false。第二次单击后,this.state.isActive 变为 true,但现在应该显示为非活动状态。 this.state.isActive 总是后退一步。
  • 你能用你试过的componentDidUpdate部分更新吗?
  • 你可以从你的 parent.js 发送函数到你的子组件并从子组件触发
  • @ShoebMirza 更正,我用 componentWillUpdate() 试过了。组件确实更新了。但是,只有当我检查 this.state.isActive !== this.props.active 之前,否则我会收到最大更新深度错误。

标签: reactjs


【解决方案1】:

我需要在状态改变时调用子函数。

您可以为此使用shouldComponentUpdate 函数。在这个函数中,你可以检查 props 或 state 是否改变。如果两者中的任何一个发生了变化,您可以从shouldComponentUpdate函数中调用您想在子组件中调用的任何函数

示例

假设函数foo 是您在状态或道具发生变化时需要在子组件中调用的函数。您在子组件中定义 foo 函数,然后在此子组件中定义 shouldComponentUpdate 函数

class Child extends Component {
  state = {
    isActive: this.props.active
  };

  foo() {
    console.log('function called when state or props change');
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (
         this.props.isActive != nextProps.active || 
         this.state.isActive != nextState.isActive
    ) {
        this.foo();   // call function on state or props change
        return true;
    }

    return false;
  }


  render() {
    return <p>{this.state.isActive ? 'active' : 'not active'}</p>
  }
} 

【讨论】:

    【解决方案2】:

    我不完全理解这个问题,您将活动从父母传递给可以由父母切换的子项,其中活动也可以由子项切换。如果这就是您所需要的,那么我不明白为什么 Child 需要有状态:

    function App() {
      const [active, setActive] = React.useState(true);
    
      return (
        <div>
          <label>
            parent
            <input
              type="checkbox"
              onChange={e => setActive(a => !a)}
              checked={active}
            />
          </label>
          <Display active={active} setActive={setActive} />
        </div>
      );
    }
    function Display({ active, setActive }) {
      //can set active from child as well based on
      //  any logic you want
      return (
        <label>
          child
          <input
            type="checkbox"
            onChange={e => setActive(a => !a)}
            checked={active}
          />
        </label>
      );
    }
    ReactDOM.render(<App />, document.getElementById('root'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      【解决方案3】:

      在 React 中,父母可以将道具传递给孩子,但反之则不行。在您的情况下,您通过道具将状态传递给孩子。收到的道具不能被孩子修改。您可以通过在父级中处理副作用的函数来实现您想要的,然后将其作为道具传递给子级,并根据您希望更新状态的情况从子级触发它。

      解决方案是将函数从父级传递给子级。这个函数会更新父状态,因为你将父状态传递给子状态,它也会被更新。

      i.e you can pass a function as a prop to the child component, so the child component can call this function to update the parent component, then call this function in child passing in updated state.

      【讨论】:

      • 是的,请看我原来的问题:handleDisplayChange in parent 可以做到这一点,但它不属于那里。
      猜你喜欢
      • 2017-06-18
      • 2019-06-05
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      相关资源
      最近更新 更多