【问题标题】:Reactjs : How to change props data from parent component that already distribute to child component?Reactjs:如何更改已经分发到子组件的父组件的道具数据?
【发布时间】:2018-08-24 16:30:07
【问题描述】:

我只是创建一个项目并为一个页面使用多个组件,并通过使用道具将数据传递给每个组件。问题是,当我已经使用道具将数据从父组件更改为子组件并且我已经更新了父组件的数据时,子组件仍然使用旧数据。 例子是这样的:

class Child extends Component{
  constructor(props){
    super(props);
    this.state = {
      variabel : props.variable
    }
  }

  render() {
    return (
      <div>
        <h1>{this.state.variable}</h1>
      </div>
    )
  }
}


class Parent extends Component{
  constructor(props){
    super(props);
    this.state = {
      variabel : 'Hello'
    }
  }
  render() {
    return (
      <div>
        <Child variable={this.state.variable} />
      </div>
    )
  }
}

所以,当我运行页面并更新父组件中的variabel 状态时,子组件仍然显示旧值。如何使其更新为父组件数据?或者我必须在这种情况下使用 Redux?

【问题讨论】:

  • 我想你在这里有一个typo。 variable 与 variabel 不同
  • 是的,这似乎是问题所在。不过,快速建议不要使用 props 声明 Child 的 state 属性。我的意思是你应该直接在子组件中使用道具作为

    {this.props.variable}

    。这样,您的事实来源就保持一致
  • 如何更新数据?如果 Child 或 Parent 重新渲染,子组件将发生变化。如果状态发生变化,则会发生重新渲染。如果您的孩子没有改变;那么,这可能与您更改数据的方式有关。

标签: javascript reactjs


【解决方案1】:

一般来说,您只想将一个特定的状态保存在一个地方。如果你在Child的构造函数中重新赋值,它不会在父状态更新时更新。所以像这样的模式应该可以工作:

class Child extends Component{
  // Note that no constructor is needed as you are not initializing any state or binding any methods.    
  render() {
    return (
      <div>
        <h1>{this.props.variable}</h1>
      </div>
    )
  }
}


class Parent extends Component{
  constructor(props){
    super(props);
    this.state = {
      variable : 'Hello'
    }
  }
  render() {
    return (
      <div>
        <Child variable={this.state.variable} />
      </div>
    )
  }
}

事实上,React docs for constructor 中有一条关于不使用 props 初始化状态的警告说明。

【讨论】:

  • 这并没有解决操作的问题...作为评论更好。
【解决方案2】:

Mitch Lillie 的答案是正确的。你应该只有一个事实来源。 一般来说,将状态保存在依赖于状态的组件的最近共同祖先中是一个好主意。然后你把道具传下来。

但是,如果您需要在子状态下保留 prop 的副本,则应使用 React provides 的生命周期。

Codepen Live Demo

class Child extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      variable: props.variable,
    };
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    if (this.props.variable !== prevState.variable) {
      this.setState({
        variable: this.props.variable,
      });
    }
  }

  render() {
    const varState = this.state.variable;
    const varProps = this.props.variable;

    return (
      <div>
        Child props: {varProps}
        <br />
        Child state: {varState}
      </div>
    );
  }
}

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

    setInterval(this.updateTime, 1000); // refresh every second

    this.state = {
      variable: new Date().toLocaleString(),
    };
  }

  updateTime = () => {
    this.setState({
      variable: new Date().toLocaleString(),
    });
  }

  render() {
    const time = this.state.variable;

    return (
      <div>
        <div>
          Parent: {time}
        </div>
        <Child variable={time} />
      </div>
    );
  }
}

ReactDOM.render(
  <Parent />,
  document.getElementById('container')
);

【讨论】:

  • 这并没有解决 OP 的问题,最好作为对建议这一点的 cmets 的回复......
  • 除了它确实解决了这个问题。问题是:如何让它更新为父组件数据?或者我必须在这种情况下使用 Redux? 我的回答显示了 OP 问题的解决方案。
猜你喜欢
  • 2018-12-07
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 2018-08-06
  • 1970-01-01
  • 2019-11-26
相关资源
最近更新 更多