React bileşeninin boole durumu nasıl değiştirilir?


90

React bileşeninin boole durumunu nasıl değiştireceğimi bilmek istiyorum. Örneğin:

Bileşenimin yapıcısında mantıksal durum denetimi var:

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

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

This.setState yöntemini kullanarak onay kutum her tıklandığında durumu değiştirmeye çalışıyorum:

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

Elbette bir Yakalanmamış Referans Hatası alıyorum : kontrol tanımlanmadı . Peki bunu nasıl başarabilirim?

Şimdiden çok teşekkürler.


3
Tam olarak söylediği gibi, çek tanımsızdır. Muhtemelen yazmak istedim this.state.checkiçinde this.setState({check: !check.value}). Ve bileşen durumuna göre değişecek olan onay kutusu için işaretlenen özelliği ekleyin. checked={this.state.checked}
vinkaları Stonys

Yanıtlar:


260

Bunu kimse göndermediğinden, doğru cevabı gönderiyorum. Yeni durum güncellemeniz önceki duruma bağlıysa, her zaman setStateyeni bir durum döndüren bir işlevi bağımsız değişken olarak kabul eden işlevsel biçimini kullanın .

Senin durumunda:

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

Belgelere bakın


Bu cevap popüler hale geldiğinden, React Hooks için kullanılması gereken yaklaşımı ekleyerek (v16.8 +):

Eğer kullanıyorsanız useStatekanca, o zaman aşağıdaki kodu kullanabilirsiniz (ihtimaline karşı yeni devlet önceki durumuna bağlıdır):

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

4
neden bu doğrudan kullanmaktan daha iyidir this.setState({check: !this.state.check})?
SunnyPro

11
@SunnyPro Bağlantılı belgeleri okuyun ve cevabınızı bulacaksınız. TL; DR react, çağrıları birlikte gruplayarak durumu ayarlamak için optimize eder. Öyleyse basit bir artış fonksiyonu increment = () => this.setState({count: this.state.count + 1});ve bir kod bloğu hayal edin : increment(); increment(); increment();Şimdi tepki, bunları aşağıdakilere benzer bir şekilde gruplayabilir: setNewState = (oldState) => { newState.count = oldState.count + 1; newState.count = oldState.count + 1; newState.count = oldState.count + 1; return newState; } Sorunun nerede yattığını görüyor musunuz?
Drew Reese

aynı anda önceki duruma bağlı olmayan diğer durum özelliklerini güncellemem gerekirse ne olur? Örneğin, doğru / yanlış olarak görünür olan ancak duruma bağlı olarak değişen bir açılır pencere mesajını değiştirmek?
hamncheez

1
@hamncheez Fonksiyonun dönüş değeri zaten sizin yeni durumunuzdur. Önceki durumdaki değerleri kullanabilir veya kullanmayabilirsiniz; böylece farklı mesajlar gibi herhangi bir değeri gönderebilirsiniz.
Dane

16

Bunun this.state.checkyerine kullanmalısınız check.value:

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

Ama yine de bunu bu şekilde yapmak kötü bir uygulamadır . Onu ayrı bir yönteme taşımak ve geri aramaları doğrudan biçimlendirmeye yazmamak çok daha iyidir.


Olumlu oy verildi, ancak meraktan - bu neden "kötü uygulama"?
Fellow Stranger

2
Bu sadece kötü bir uygulama değil, aynı setStatezamanda eşzamansız olduğu gibi istenen sonucu da alamayabilirsiniz . Aşağıdaki cevabıma bakın.
Dane

1
Yeni durumun önceki duruma bağlı olması durumunda kullanılması amaçlanan React'in API'sini kullandığından Dane'in cevabının daha iyi bir yaklaşımı olduğunu düşünüyorum.
MT.

3
@MT. Ama sonra yıllar sonra cevapladım. İşte bu :)
Dane

1
This.state eşzamansız olduğundan, sonraki durumu güncellemek için hiçbir zaman değerine güvenmemelisiniz. Bunun yerine @Dane'in önerdiği gibi bir işlev geri arama kullanın.
Dr Younes Henni

5

checkedDeğeri almak için kullanın . Sırasında onChange, checkedolacak trueve bir tür olacak boolean.

Bu yardımcı olur umarım!

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>


4

İşte kanca kullanan bir örnek (React> = 16.8.0 gerektirir)

// 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>


3

useStateBir fonksiyon bileşeni için yerel durumu bildirmek için React'in kancasını da kullanabilirsiniz . Değişkenin başlangıç ​​durumu toggled, yönteme argüman olarak aktarıldı .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


2

Deneyin:

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

Kullanmak check: !check.value, açıklamadığınız checknesneyi aradığı anlamına gelir .

Ters değerini istediğinizi belirtmeniz gerekir this.state.check.


2

Boole değerleri arasında geçiş yaparken bunu en basit buldum. Basitçe ifade etmek gerekirse, değer zaten doğruysa, onu yanlış olarak ayarlar ve bunun tersi de geçerlidir. Tanımlanmamış hatalara dikkat edin, çalıştırmadan önce mülkünüzün tanımlandığından emin olun

this.setState({
   propertyName: this.propertyName = !this.propertyName
});

1

Bağlamınıza bağlı olarak; bu, mouseEnter işlevi verilen durumu güncellemenize izin verecektir. Her iki durumda da, bir durum değerini true: false olarak ayarlayarak, herhangi bir işlev verilen bu durum değerini, onu karşıt değere ayarlayarak güncelleyebilirsiniz.!this.state.variable

state = {
  hover: false
}

onMouseEnter = () => {
  this.setState({
    hover: !this.state.hover
  });
};

0

Redux kullanarak React bileşeninde geçiş durumunu kullanmak için ararken bu sayfaya iniş yaptım, ancak burada aynı şeyi kullanan herhangi bir yaklaşım bulamıyorum.

Bu yüzden, Redux kullanarak geçiş durumunu uygulamak için mücadele eden birine yardımcı olabileceğini düşünüyorum.

Redüktör dosyam buraya gelir. Varsayılan olarak ilk durumu yanlış alıyorum .

const INITIAL_STATE = { popup: false };
export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case "POPUP":
            return {
                ...state,
                popup: action.value
            };
        default:
            return state;
    }
    return state;
};

Resmi tıklayarak durumu değiştiriyorum. Yani, img etiketim onClick işlevi ile buraya gelir.

<img onClick={togglePopup} src={props.currentUser.image} className="avatar-image avatar-image--icon" />

Toggle Popup işlevim, Dispatcher'ı çağıran aşağıdadır.

const togglePopup = ev => {
    ev.preventDefault();
    props.handlePopup(!props.popup);
};

Bu çağrı, geçiş durumunu geri yansıtan mapDispatchToProps işlevinin altına gider.

const mapDispatchToProps = dispatch => ({
    handlePopup: value => dispatch({ type: "POPUP", value })
});

Teşekkür ederim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.