【问题标题】:Why my state doesn't update even in callback?为什么即使在回调中我的状态也不更新?
【发布时间】:2019-08-20 11:32:51
【问题描述】:

我调用一个函数来使用 onClick 更改我的状态,一个状态位于父组件中(我使用传入 props 的函数更改它)和另一个状态位于我的组件中。 第一个工作正常, 但是第二个没有更新,即使我测试它并在回调中调用结果。

我在 setState 之前的函数和回调中放置了一些控制台日志,它记录但不改变保持不变的状态

class CaseProducts extends Component {
  state = {
    position_selector: 0,
    case_sales: "-100%",
    case_products: "0%",
  };

  changeSelector = () => {
    console.log(this.props);
    if (!this.props.products_on) {
      console.log("product: off");
      this.setState(
        { position_selector: -106, case_sales: 0, case_products: "-100%" },
        () => console.log(this.state.position_selector),
      );
    } else {
      console.log("product_on");
      this.setState(
        { position_selector: 0, case_sales: "-100%", case_products: "0%" },
        () => console.log(this.state.position_selector),
      );
    }
  };
  render() {
    return (
      <div className="button-category">
        <div
          className="blue-button"
          style={{ right: this.state.position_selector }}
        >
          <text className="position-selector-products">Produits</text>
          <text className="position-selector-sales">Ventes</text>
        </div>
        <button
          className="change-button-sales"
          onClick={() => {
            this.props.updateDatas();
            this.changeSelector();
          }}
        >
          Ventes
        </button>
        <button
          className="change-button-products"
          onClick={() => {
            this.props.updateDatas();
            this.changeSelector();
          }}
        >
          Produits
        </button>
      </div>
    );
  }
}

class App extends Component {
  state = { products_on: true };

  updateDatas = () => {
    console.log("bonjourrrrr");
    this.setState({ products_on: !this.state.products_on });
  };

  render() {
    return (
      <Router>
        <Route
          exact
          path={ROUTES.HOME}
          component={props => (
            <CaseProducts
              {...props}
              products_on={this.state.products_on}
              updateDatas={this.updateDatas}
            />
          )}
        />
      </Router>
    );
  }
}

product_on 的 setState 工作正常,只是 change_selector、case_sales 和 product_sales 的 setState 根本不更新。

有人知道它可能是什么吗?

【问题讨论】:

  • 我将您的代码添加到codepen,它按预期工作。您能否验证笔是否按要求工作?

标签: javascript reactjs


【解决方案1】:

可能发生的情况是,您正在根据传递的属性创建一个新的内部状态。就像您不知道哪个“将首先结束”。

如果你想根据传递的属性更新内部状态,你应该改用getDerivedStateFromProps 方法(在以前版本的 React 中,可能是componentWillReceiveProps 方法)

class CaseProducts extends React.Component {
  state = {
    position_selector: 0,
    case_sales: '-100%',
    case_products: '0%'
  };

  static getDerivedStateFromProps(nextProps) {
    if (!nextProps.products_on) {
      return ({
        position_selector: -106,
        case_sales: 0,
        case_products: '-100%'
      });
    } else {
      return ({
        position_selector: 0,
        case_sales: '-100%',
        case_products: '0%'
      });
    }
  }

  render() {

    return ( <
      div className = 'button-category' >
      <
      div className = 'blue-button'
      style = {
        {
          right: this.state.position_selector
        }
      } >
      <
      text className = 'position-selector-products' > Produits < /text> <
      text className = 'position-selector-sales' > Ventes < /text> <
      /div> <
      button className = 'change-button-sales'
      onClick = {
        () => {
          this.props.updateDatas()
        }
      } >
      Ventes <
      /button> <
      button className = 'change-button-products'
      onClick = {
        () => {
          this.props.updateDatas()
        }
      } >
      Produits <
      /button> <
      /div>  
    )
  }
}


class App extends React.Component {

  state = {
    products_on: true
  }

  updateDatas = () => {
    console.log('bonjourrrrr');
    this.setState({
      products_on: !this.state.products_on
    })
  }

  render() {
    return ( <
      CaseProducts products_on = {
        this.state.products_on
      }
      updateDatas = {
        this.updateDatas
      }
      />
    );
  }
}

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

【讨论】:

【解决方案2】:

问题是,当您调用 this.props.updateDatas(); 时,此方法会导致父级中的状态更改,这将导致包含子级 CaseProducts 的父级重新渲染,从而导致重新渲染和 state 重置。这就是为什么CaseProducts 状态没有改变!

尝试删除 this.props.updateDatas() 并检查 CaseProducts 组件中的状态变化。

【讨论】:

  • 它可以工作,但我也需要在 this.props.upadateDatas() 之后使用 this.changeSelector(),我该怎么做?
  • @Constantin 最好的方法是使用像 redux 这样的全局状态管理,您可以将所有应用程序状态保存在一个名为 store 的地方并检索所需的状态。或者您可以添加一个新属性,让我们在您的父级中将其命名为 button_number 并根据从子级单击的按钮对其进行更改,然后将其作为道具传递给您的子级,以检查每个渲染是否单击了任何按钮。
【解决方案3】:

可能子组件中的函数changeSelector中的this.setState错误,您必须按照以下方式进行更改。

changeSelector = () => {
        console.log(this.props);
        if (!this.props.products_on) {
            console.log('product: off');
            this.setState({ position_selector: -106, case_sales: 0, case_products: '-100%' }); 
            console.log(this.state.position_selector);
        } else {
            console.log('product_on');
            this.setState({ position_selector: 0, case_sales: '-100%', case_products: '0%' });
            console.log(this.state.position_selector));
        }
    }

【讨论】:

  • 你错了他使用setState 回调来检查状态是否更新!
  • 是的,我正在使用 setState 回调来检查它是否更新但它没有更新:((((
  • 我认为setState 语法是错误的。它的结构类似于this.setState({field: 'new value'})。不是this.setState( { position_selector: -106, case_sales: 0, case_products: "-100%" }, () =&gt; console.log(this.state.position_selector), )。在setState 函数中不允许使用此函数() =&gt; console.log(this.state.position_selector)
  • @TrầnCông 不,你错了,它是 setstate 中允许的回调函数
猜你喜欢
  • 2019-12-21
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2020-11-20
  • 2020-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多