如何切换react组件的布尔状态?

IT技术 javascript reactjs reactjs-flux
2021-04-12 22:49:42

我想知道如何切换react组件的布尔状态。例如:

我在组件的构造函数中进行了布尔状态检查:

constructor(props, context) { 
   super(props, context);

   this.state = {
      check: false
   };
};

每次单击复选框时,我都尝试使用 this.setState 方法切换状态:

<label><input type=checkbox" value="check" onChange = {(e) => this.setState({check: !check.value})}/> Checkbox </label>

当然我得到一个Uncaught ReferenceError: check is not defined那么我怎样才能做到这一点呢?

提前谢谢了。

6个回答

由于没有人发布这个,我发布了正确的答案。如果您的新状态更新取决于之前的状态,请始终使用其函数形式,setState它接受一个返回新状态的函数作为参数。

在你的情况下:

this.setState(prevState => ({
  check: !prevState.check
}));

查看文档


由于这个答案变得流行,添加应该用于 React Hooks (v16.8+) 的方法:

如果您正在使用useState钩子,则使用以下代码(以防您的新状态依赖于以前的状态):

const [check, setCheck] = useState(false);
// ...
setCheck(prevCheck => !prevCheck);
如果我需要同时更新不依赖于先前状态的其他状态属性怎么办?例如,切换弹出消息,可见为真/假,但消息根据状态而变化?
2021-05-26 22:49:42
因为我们正在处理布尔值,所以钩子语句不应该是: setCheck(prevCheck => !prevCheck) 吗?
2021-05-26 22:49:42
为什么这比直接使用更好this.setState({check: !this.state.check})
2021-05-27 22:49:42
@SunnyPro 阅读链接的文档,您将找到答案。TL;DR 是 react 通过将它们批处理来优化对设置状态的调用。所以想象一个简单的增量函数increment = () => this.setState({count: this.state.count + 1});和一个代码块:increment(); increment(); increment();现在 react 可能会将它们批处理成类似于:setNewState = (oldState) => { newState.count = oldState.count + 1; newState.count = oldState.count + 1; newState.count = oldState.count + 1; return newState; } 看看问题出在哪里?
2021-05-29 22:49:42
@hamncheez 函数的返回值无论如何都是你的新状态。您可能会或可能不会使用先前状态的值;所以你可以发送任何值,比如不同的消息。
2021-05-30 22:49:42

你应该使用this.state.check而不是在check.value这里:

this.setState({check: !this.state.check})

但无论如何,这样做不好的做法最好将它移动到单独的方法中,并且不要直接在标记中编写回调。

更新: 正如评论中所指出的,这种方法可能会导致意外结果,因为 React 的状态是异步的。在这种情况下,正确的方法是使用回调:

this.setState(({ check }) => ({ check: !check }));
这不仅是不好的做法,而且您可能无法获得所需的结果,setStateasync 也是如此请看我下面的回答。
2021-05-31 22:49:42
@公吨。但是,几年后我回答了。有那个:)
2021-06-01 22:49:42
赞成,但出于好奇 - 为什么这是“不好的做法”?
2021-06-04 22:49:42
由于 this.state 是异步的,你永远不应该依赖它的值来更新下一个状态。按照@Dane 的建议使用函数回调。
2021-06-04 22:49:42
我认为 Dane 的答案有更好的方法,因为它使用了 React 的 API,旨在在新状态依赖于先前状态的情况下使用。
2021-06-06 22:49:42

这是一个使用钩子的例子(需要 React >= 16.8.0)

// import React, { useState } from 'react';
const { useState } = React;

function App() {
  const [checked, setChecked] = useState(false);
  const toggleChecked = () => setChecked(value => !value);
  return (
    <input
      type="checkbox"
      checked={checked}
      onChange={toggleChecked}
    />
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"><div>

使用checked来获取值。期间onChangechecked将是true,它将是一种boolean

希望这可以帮助!

class A extends React.Component {
  constructor() {
    super()
    this.handleCheckBox = this.handleCheckBox.bind(this)
    this.state = {
      checked: false
    }
  }
  
  handleCheckBox(e) {
    this.setState({
      checked: e.target.checked
    })
  }
  
  render(){
    return <input type="checkbox" onChange={this.handleCheckBox} checked={this.state.checked} />
  }
}

ReactDOM.render(<A/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

您还可以使用 React 的useState钩子来声明函数组件的本地状态。变量的初始状态toggled已作为参数传递给方法.useState

import { render } from 'react-dom';
import React from "react";

type Props = {
  text: string,
  onClick(event: React.MouseEvent<HTMLButtonElement>): void,
};

export function HelloWorldButton(props: Props) {
  const [toggled, setToggled] = React.useState(false); // returns a stateful value, and a function to update it
  return <button
  onClick={(event) => {
    setToggled(!toggled);
    props.onClick(event);
  }}
  >{props.text} (toggled: {toggled.toString()})</button>;
}


render(<HelloWorldButton text='Hello World' onClick={() => console.log('clicked!')} />, document.getElementById('root'));

https://stackblitz.com/edit/react-ts-qga3vc