Vyhledávání na webu

javascript - Jak přepínat boolean stav komponenty React?


Rád bych věděl, jak přepnout boolean stav komponenty React. Například:

Mám kontrolu stavové proměnné typu boolean v konstruktoru mé komponenty:

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

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

Snažím se přepínat stav pokaždé, když je moje zaškrtávací políčko kliknuto, pomocí metody this.setState:

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

Samozřejmě dostávám Uncaught ReferenceError: check is not defined. Jak to tedy mohu dosáhnout?

Odpověď č. 1

Pokud vaše nová aktualizace stavu závisí na předchozím stavu, vždy použijte funkční formu setState, která jako argument přijímá funkci vracející nový stav.

Ve vašem případě:

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

Podívejte se na dokumentaci


Jelikož se tato odpověď stává populární, přidávám přístup, který by měl být použit pro React Hooks (v16.8+):

Pokud používáte hook useState, použijte následující kód (v případě, že váš nový stav závisí na předchozím stavu):

const [check, setCheck] = useState(false);
// ...
setCheck(prevCheck => !prevCheck);

Aktualizace [květen 2023]:

Relevantní sekce v dokumentaci: https://react.dev/reference/react/useState#updating-state-based-on-the-previous-state

Odpověď č. 2

Měli byste zde použít this.state.check místo check.value:

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

Ale každopádně je špatná praxe dělat to tímto způsobem. Je mnohem lepší přesunout to do samostatné metody a nepíšejte callbacky přímo v značkování.

Aktualizace: Jak bylo zmíněno v komentářích, tento přístup může vést k neočekávaným výsledkům, protože stav Reactu je asynchronní. Správný způsob v tomto případě bude použít callback:

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

Odpověď č. 3

Zde je příklad použití hooků (vyžaduje 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>

Související články