【问题标题】:How pass data from the child component (the child has its own state) to the parent?如何将数据从子组件(子组件有自己的状态)传递给父组件?
【发布时间】:2019-06-11 07:47:19
【问题描述】:

预期效果:单击按钮 -> 调用函数 setEditing() -> 在 setEditing() 中调用函数 item() -> this.state.isEditing 更改为 true -> 父级中的 this.state.isEdit 更改为 true。当我调用item()函数时,isEditing的值没有变化

应用

class App extends React.Component {
  constructor() {
    super();

    this.state = {
        isEdit = false; 
    };
  }

  handleSomething = (value) => {
    this.setState(prevState => {
      return {
        isEdit: value
      };
    });
  }


  render() {
    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                  handleSomething={this.handleSomething}
                />
              )
          }
        </ul>
      </div>
    );
  }
}

待办事项

class Todo extends Component {

  state = {
    isEditing: false
  }

  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    })

    this.item();
  }

  item = () => { 
    const { isEditing} = this.state;
    this.props.handleSomething(isEditing);
  }

  render() {
    return ( 
        <button onClick={() => this.setEditing()}>Edit</button>

    )
  }
}

【问题讨论】:

  • 如果你需要在调用item之前状态肯定已经更新,你需要使用setState的第二个参数。
  • 代码看起来不错,我认为问题必须处于状态必须为 isEditing 制作控制台并尝试过?
  • 我检查了 console.log。 isEditing 总是错误的
  • 那么发布的答案就可以解决问题setEditing = () =&gt; { this.setState({ isEditing: !this.state.isEditing },()=&gt; this.item()) }
  • 更改 this.state = { isEdit = false; }; to this.state = { isEdit : false };

标签: javascript reactjs ecmascript-6


【解决方案1】:

你需要在状态改变后调用this.item,比如

setEditing = () => {
  this.setState({
    isEditing: !this.state.isEditing
  }, this.item)
}

此外,如果您想从旧状态中导出新状态,则必须使用以下内容:

setEditing = () => {
  this.setState(prevState => ({
    isEditing: !prevState.isEditing
  }), this.item)
}

【讨论】:

  • 在函数 handleSomething 我必须更改为 handleSomething = (value) =&gt; { this.setState({ isEdit: value }); } ;我不需要prevState
  • @Umbro 你不需要prevState,因为新状态不是从旧状态派生的。
  • 这个prevState下面隐藏了什么?它是如何在引擎盖下工作的?
  • @Umbro 你可以找到更多关于HERE的详细信息
【解决方案2】:

尝试根据之前的状态更改您的状态,并在回调中调用父函数:

setEditing = () => {
  this.setState(prevState => ({
    isEditing: !prevState.isEditing
  }), this.item)
}

因为正如 React 文档中所写:

setState() 并不总是立即更新组件。它可能 批处理或推迟更新。这使得阅读 this.state 就在调用 setState() 之后,这是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调(setState(updater, 回调)),其中任何一个都保证在更新后触发 已应用。如果需要根据前面的设置状态 状态,请阅读下面的更新程序参数。 (https://reactjs.org/docs/react-component.html#setstate)

【讨论】:

  • 在函数 handleSomething 我必须更改为 handleSomething = (value) => { this.setState({ isEdit: value }); } ;我不需要 prevState?
  • 不,这个函数不需要它,你可以直接写handleSomething = value =&gt; this.setState({ isEdit: value });。还要检查您在 App 组件中的状态声明,您有一个错字:将 isEdit = false; 更改为 isEdit: false;
  • 这个prevState下面隐藏了什么?它是如何在引擎盖下工作的?
【解决方案3】:

class Todo extends React.Component {

  state = {
    isEditing: false
  }

  setEditing = () => {
    this.setState({
      isEditing: !this.state.isEditing
    },this.item())
  }

  item = () => { 
    const { isEditing} = this.state;
    this.props.handleSomething(isEditing);
  }

  render() {
    return ( 
        <button onClick={() => this.setEditing()}>
          Edit
         </button>
    )
  }
}

class App extends React.Component {
  constructor() {
    super();

    this.state = {
        isEdit : false,
        todos : [
          "test 1",
          "test 2"
        ]
    };
  }

  handleSomething = (value) => {
    this.setState(prevState => {
      return {
        isEdit: value
      };
    });
  }


  render() {
    return (
      <div>
        <ul>
          {
            this.state.todos
              .map((todo, index) =>
                <Todo
                  key={index}
                  index={index}
                  todo={todo}
                  handleSomething={this.handleSomething}
                />
              )
          }
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
<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="app"></div>

【讨论】:

    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 2022-07-15
    • 2019-04-02
    • 2014-12-18
    • 2020-06-21
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多