【问题标题】:How to fix setState() gives the opposite value of checkbox?如何修复 setState() 给出复选框的相反值?
【发布时间】:2020-12-10 08:19:03
【问题描述】:

这是我的类组件:

import React from 'react';

import { Jumbotron, Container, Label } from 'reactstrap';

import './Css.css';

class Settings extends React.Component {

  state = {
    isChecked: false,
  }

  isCheck(e) {
    this.setState({
      isChecked: e.target.checked
    })
    console.log(e.target.checked)
    console.log(this.state.isChecked)
  }


  render() {
    return (
      <div className="margin">
        <Jumbotron fluid>
          <Container fluid>
            <h1 className="display-3">Settings</h1>

            <div className="groupbox">
              <Label className="lead">This is a checkbox</Label>
              <input class="apple-switch" type="checkbox" onChange={e => this.isCheck(e)} />
            </div>

          </Container>
        </Jumbotron>
      </div>
    );
  }
}

export default Settings;

我遇到的问题是我在控制台中得到的值是相反的。

所以当复选框未选中时e.target.checkedfalsethis.state.isCheckedtrue,当复选框被选中时e.target.checkedtruethis.state.isCheckedfalse

我不知道为什么会遇到这个问题。

  • 我做错了什么吗?

我还尝试将e.target.checked 存储到const checked,然后将其传递给setState(),但它给了我同样的东西。

感谢任何帮助。

【问题讨论】:

  • 这能回答你的问题吗? React setState not Updating Immediately TL;DR React 状态更新是异步的,并且在 渲染周期之间进行批处理,您只需记录 当前 渲染周期的状态与排队等待的状态下一个 渲染周期。如果要记录状态更新,请使用 componentDidUpdate 生命周期函数或 setState 回调。
  • @DrewReese 不,它没有。
  • 事实上,确实如此......这个问题几乎每天都会被问到。我刚刚进行了搜索,这是结果中投票数最高的第一个。
  • @DrewReese 用this.state.isChecked = e.target.checked 代替setState() 好不好?因为它给了我想要的东西。
  • 这将是一个状态突变,应该避免。 reactjs.org/docs/state-and-lifecycle.html#using-state-correctly

标签: reactjs class checkbox setstate


【解决方案1】:

这个问题纯粹是一个日志记录问题。在设置值和看到它更新状态之间存在延迟。试试:

  isCheck(e) {
    console.log(e.target.checked);
    this.setState({
      isChecked: e.target.checked
    }, () => {
      console.log(this.state.isChecked);
    });
  }

如果您需要在状态更新后 做某事,则将其放入setState 调用内的回调函数中,如上所述。这样做的原因是 setState 调用 render(这是它的主要目的),当它准备好时,React 会异步执行此操作。

【讨论】:

  • 它在console.log(e.target.checked) 中给了我一个错误?
  • @YounessSaadna 控制台日志本质上也是异步的,因此反应合成事件可能已被无效并返回到事件池。只需将检查的值保存在函数中,即const { checked } = e.target; 或持久化事件对象e.persist(); 以防止它被无效并返回。 reactjs.org/docs/events.html#event-pooling
  • console.log 不是异步的(或者至少不清楚它是否是异步的),但重点是正确的——在回调运行时事件已经丢失。我已经更新了答案。请注意,这并不重要。您对日志不感兴趣,您对设置值感兴趣,这从一开始就起作用。你只是被日志误导了。
【解决方案2】:

根据doc

setState() 视为更新组件的请求而不是立即命令

setState() 并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用 setState() 之后立即阅读 this.state 是一个潜在的陷阱。相反,请使用componentDidUpdate setState 回调 (setState(updater, callback)),保证在应用更新后触发其中任何一个

所以setState()这里是异步的,所以在你的情况下,要查看效果,只需使用回调(这里我使用箭头函数来维护this的上下文)

isCheck(e) {
  this.setState(
    {
      isChecked: e.target.checked,
    },
    () => {
      console.log(e.target.checked)
      console.log(this.state.isChecked)
    }
  )
}

【讨论】:

    猜你喜欢
    • 2019-09-27
    • 2018-08-15
    • 1970-01-01
    • 2014-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2019-07-10
    相关资源
    最近更新 更多