【问题标题】:Passing state to another component immediately after setState在 setState 之后立即将状态传递给另一个组件
【发布时间】:2018-06-08 15:43:21
【问题描述】:

我有一个存储状态的主要组件,并有一个名为 handleBtnClick 的函数来操作状态值。

我有另一个组件,它在按下按钮时调用函数 handleBtnClick。我有一个 displayComponent,我传递状态值以在表单中显示。

我知道 setState 是异步的,所以 displayComponent 的值总是落后一步。如何使用 setState 中的回调解决此问题,还是有其他方法?

主组件

class SomeComponent extends React.Component {
  constructor (props) {
    super (props)
    this.state = {value: 1}
  }

  handleBtnClick = (values) => {      
    const newValue = this.state.value * values;
    this.setState({value: newValue});
  }

  render() {
    return (
      <div>
        <ButtonComponent onClick={this.handleBtnClick} />              
        <DisplayComponent displayValue={this.state.value}/>
      </div>
    );
  }
}

按钮组件

class ButtonComponent extends React.Component {
  render() {
    return (
      <div>
        <button onClick={() => this.props.onClick(123)}> // pretent this value always changes
                    Button
        </button>
      </div>
    );
  }
}

显示组件

class DisplayComponent extends React.Component {
  render() {
    return (
      <div>
        {this.probs.displayValue}
      </div>
    );
  }
}

编辑:

此处为沙盒示例(感谢 Shubham):https://codesandbox.io/s/5kx9yk7934

在第一个按钮单击时,标签中显示的值是 0,即使它应该是 4。在第二次单击时它更新为 4。

我怎样才能确保在第一次点击时该值始终正确(即 4)使用状态值进行计算。

【问题讨论】:

  • 你能解释一下“落后一步”是什么意思吗?在您发布的代码中,按钮处理程序从父级调用函数,该函数调用 setState(),这会导致 DisplayComponent 使用新值重新渲染。
  • 如果只有将this.probs.displayValue 中的类型更正为this.props.displayValue 才能按预期工作,请检查此沙箱codesandbox.io/s/00j699v4xl
  • @ouni 如果你加载这个:codesandbox.io/s/5kx9yk7934(感谢 Shubham),在第一次按钮点击时,总值仍然是 0,即使它应该是 4。在第二次点击它更新为 4 .
  • @ShubhamKhatri 在此处更新示例:codesandbox.io/s/5kx9yk7934
  • @TylarBen,setState 调用是批处理的,而且 setState 也是异步的,因此更新状态不会立即反映更改。我更新了沙箱以正常工作,检查codesandbox.io/s/xlwp6zv054。还要检查这个stackoverflow.com/questions/41278385/…

标签: javascript reactjs


【解决方案1】:

setState 将更新您的状态,并且在状态更改时,您的主要组件将重新呈现新状态,因此 yourDisplayComponent 将重新呈现。

你的 DislayComponent 有一个错字:this.probs

您的按钮和显示都可以是无状态组件:

const DisplayComponent = ({displayValue}) => <div>{displayValue}</div>

由于 react 使用 onClick 作为点击监听器,因此更喜欢传递 handleClick 属性而不是 onClick。

const ButtonComponent = ({handleClick}) => <div><button onClick={() => handleClick(123)}> </button></div>

【讨论】:

    【解决方案2】:

    在您的沙箱中,SomeComponent 组件未正确处理状态:多次调用 setState,这是异步的,并且存储了 三个 值(value1、value2 , total),当它只需要 一个(要添加的操作数堆栈)时,您可以在每次渲染时派生总数:

    import React from "react";
    import { render } from "react-dom";
    class ButtonComponent extends React.Component {
      render() {
        return (
          <div>
            <button onClick={() => this.props.onClick(2)}>
              {" "}
              // pretent this value always changes Button
            </button>
          </div>
        );
      }
    }
    class DisplayComponent extends React.Component {
      render() {
        return <div>{this.props.displayValue}</div>;
      }
    }
    
    class SomeComponent extends React.Component {
      constructor(props) {
        super(props);
        this.state = { stack: [] };
        this.get_total = this.get_total.bind(this);
      }
    
      handleBtnClick = value => {
        this.setState({ stack: this.state.stack.concat(value) });
      };
    
      get_total() {
        return this.state.stack.reduce((result, value) => {
          return result + value;
        }, 0);
      }
    
      render() {
        return (
          <div>
            <ButtonComponent onClick={this.handleBtnClick} />
            <DisplayComponent displayValue={this.get_total()} />
          </div>
        );
      }
    }
    
    render(<SomeComponent />, document.getElementById("root"));
    

    【讨论】:

    • 这对您有帮助吗?在 React 中,我们尝试存储尽可能少的状态,然后在需要时即时计算值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2017-11-07
    • 2016-12-05
    • 1970-01-01
    • 2019-09-15
    • 2021-01-23
    • 1970-01-01
    相关资源
    最近更新 更多