【问题标题】:How to update state of parent component n level above in React如何在 React 中更新父组件 n 级以上的状态
【发布时间】:2017-09-05 04:56:46
【问题描述】:

在此处检查代码 jsfiddle

我希望从子组件更新单个项目的值属性。但是由于道具是不可变的并且不会触发重新渲染,因此代码不起作用。我知道完成这项工作的一种方法是将函数从 GrandParent 传递给 Parent,然后传递给 Child,并使用它来更新 GrandpParent 的状态。这将触发子组件中的重新渲染。但这也会导致 GrandParent、Parent 和 Child 组件的其他兄弟姐妹的重新渲染。

// comment

有没有更好的方法来做到这一点,这对我来说似乎不是最佳选择。

【问题讨论】:

  • 如果你使用 redux 最好的方法是使用 mapStateToProps 和 mapDispatchToProps
  • +1 到之前的评论 - 为什么不使用 redux 呢?如果它不适合 - 使用上下文。如果它不适合 - 你自己描述了一切。只需使用键和shouldComponentUpdate' 管理重新渲染
  • 正如@donquixote 所提到的,您应该为此使用一些架构,这将很容易处理所有这些类型的场景,维护存储中的数据,并在任何级别轻松访问它。
  • 谢谢。似乎 Redux 是要走的路。将探索。

标签: javascript reactjs


【解决方案1】:
class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e) {
    this.props.handleIncrement(e.currentTarget.dataset.key)
  }

  render() {
    return (
      <div>
        <span>{this.props.item.value}</span>
        <button data-key={this.props.item.key} onClick={this.handleClick}>inc</button>
      </div>
    );
  }

}

class Parent extends React.Component {

  render() {
    return (
      <div>
        {
          this.props.list.map((item) => <Child item={item} handleIncrement={this.props.handleIncrement} />)
        }
      </div>
    );
  }

}

class GrandParent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        {
          key: 'one',
          value: 1
        },
        {
          key: 'two',
          value: 2
        },
        {
          key: 'three',
          value: 3
        }
      ]
    };

    this.handleIncrement = this.handleIncrement.bind(this)
  }

  handleIncrement(key) {
    this.setState({
        list: this.state.list.map((l) => {
        if (l.key === key) {
            return {key: l.key, value: l.value + 1}
        }
        return l
      })
    })
  }

  render() {
    return (<Parent list={this.state.list} handleIncrement={this.handleIncrement} />);
  }

}

React.render(<GrandParent />, document.getElementById('container'));

您必须从祖父传递处理程序并在您想要递增时调用此处理程序。阅读 coupling and cohesion 了解理论背景。

【讨论】:

    【解决方案2】:

    React 基于单向数据流的概念。这意味着您正在将数据向下传递给其他组件,这些组件将其作为道具接收并呈现它,或者将其向下传递给另一个子组件。

    但是,有时我们希望一个子组件让一个父组件知道某事发生了。为了解决这个问题,我们使用回调。回调是我们可以作为 props 传递给子组件的函数,因此他可以在发生某些事情时使用它们。一个经典的例子是将onClick 处理程序传递给具有按钮的子组件。然后,当按下按钮时,子组件会这样调用它:

    this.props.onClick()
    

    让父母知道按钮被点击。这也适用于您的示例。在 GrandParent 组件中创建一个知道如何递增值的函数。

    incrementValue = (idx) => {
        // Copy the list to avoid mutating the state itself.
        let newList = this.state.list.slice();
        newList[idx].value += 1;
        this.setState({list: newList});
    }
    

    然后将此函数作为回调传递

    <Parent onClick={this.incrementValue}/>
    

    然后将其绑定到按钮单击,如下所示:

    <button onClick={this.props.onClick}>inc</button>
    

    阅读this 了解更多关于 React 中的 state 和 props 的信息。

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      • 2023-03-26
      • 2018-10-09
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多