반응 구성 요소의 부울 상태를 전환하는 방법은 무엇입니까?


85

반응 구성 요소의 부울 상태를 전환하는 방법을 알고 싶습니다. 예를 들면 :

내 구성 요소의 생성자에 부울 상태 검사가 있습니다.

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가 발생 합니다. 그래서 이것을 어떻게 얻을 수 있습니까?

미리 감사드립니다.


3
정확히 말한대로, 검사는 정의되지 않았습니다. 당신은 아마 작성하는 의미 this.state.check에서 this.setState({check: !check.value}). 체크 박스에 체크 된 속성을 추가하면 컴포넌트 상태에 따라 변경됩니다. checked={this.state.checked}
Vincas Stonys

답변:


247

아무도 이것을 게시하지 않았으므로 정답을 게시하고 있습니다. 새 상태 업데이트가 이전 상태에 의존하는 경우 항상 setState새 상태를 반환하는 함수를 인수로 받아들이는 함수 형식을 사용하십시오 .

귀하의 경우 :

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

문서 보기


이 답변이 인기를 얻고 있으므로 React Hooks (v16.8 +)에 사용해야하는 접근 방식을 추가합니다.

당신이 사용하는 경우 useState후크를, 다음 코드를 사용 (경우에 대비하여 새로운 상태가 이전 상태에 따라 다름) :

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

4
직접 사용하는 것보다 왜 더 나은 this.setState({check: !this.state.check})가요?
SunnyPro

10
@SunnyPro 링크 된 문서를 읽으면 답을 찾을 수 있습니다. TL; DR은 상태를 설정하기위한 호출을 함께 일괄 처리하여 최적화합니다. 따라서 간단한 증분 함수 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; } 있습니다. 문제가 어디에 있는지 보십니까?
Drew Reese

이전 상태에 동시에 의존하지 않는 다른 상태 속성을 업데이트해야하는 경우 어떻게합니까? 예를 들어 참 / 거짓으로 표시되지만 상태에 따라 메시지가 변경되는 팝 오버 메시지를 토깅합니까?
hamncheez

1
@hamncheez 함수의 반환 값은 어쨌든 새로운 상태입니다. 이전 상태의 값을 사용하거나 사용하지 않을 수 있습니다. 따라서 다른 메시지와 같은 모든 값을 보낼 수 있습니다.
데인

17

여기 this.state.check대신 사용해야 합니다 check.value.

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

그러나 어쨌든 이렇게하는 것은 나쁜 습관 입니다. 별도의 메서드로 이동하고 마크 업에 직접 콜백을 작성하지 않는 것이 훨씬 좋습니다.


찬성했지만 호기심에서-왜이 "나쁜 관행"입니까?
Fellow Stranger

뷰와 로직을 분리하는 것이 좋습니다. 이렇게하면 로직과 마크 업을 개별적으로 더 쉽게보고 업데이트 할 수 있기 때문입니다.
Eugene Tsakh

2
이것은 나쁜 습관이 아니지만 setStateasync 처럼 원하는 결과를 얻지 못할 수도 있습니다 . 아래 내 대답을 참조하십시오.
Dane

1
Dane의 대답은 새로운 상태가 이전 상태에 의존하는 경우에 사용되는 React의 API를 사용하기 때문에 더 나은 접근 방식을 가지고 있다고 생각합니다.
MT.

3
@산. 하지만 몇 년 후에 대답했습니다. 이 : 거기
덴마크

5

checked값을 얻기 위해 사용 합니다. 동안 onChange, checked이 (가) 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>


4

다음은 후크를 사용한 예입니다 (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>


3

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


2

시험:

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

사용 check: !check.value한다는 check것은 선언하지 않은 객체를 찾는다는 의미 입니다.

의 반대 값을 원하도록 지정해야합니다 this.state.check.


2

부울 값을 토글 할 때 이것이 가장 간단하다는 것을 알았습니다. 값이 이미 참이면 간단히 말하면 거짓으로 설정되고 그 반대의 경우도 마찬가지입니다. 정의되지 않은 오류에주의하고 실행하기 전에 속성이 정의되었는지 확인하십시오.

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

! 감사합니다. 그것은 나를 위해 일했습니다.
Mo1

2

상황에 따라 다릅니다. 이렇게하면 mouseEnter 함수가 주어진 상태를 업데이트 할 수 있습니다. 어느 쪽이든, 상태 값을 true : false로 설정하면 모든 함수에 대해 상태 값을 반대 값으로 설정하여 업데이트 할 수 있습니다.!this.state.variable

state = {
  hover: false
}

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

0

Redux를 사용하여 React 구성 요소에서 토글 상태를 사용하려고 검색 할 때이 페이지에 도착했지만 여기서는 동일한 방법을 사용하는 방법을 찾지 못했습니다.

따라서 Redux를 사용하여 토글 상태를 구현하는 데 어려움을 겪고있는 사람에게 도움이 될 것이라고 생각합니다.

내 감속기 파일이 여기에 있습니다. 기본적으로 초기 상태가 false 입니다.

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;
};

이미지를 클릭하면 상태를 변경합니다. 따라서 내 img 태그는 onClick 기능과 함께 여기에 있습니다.

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

내 Toggle Popup 기능은 Dispatcher를 호출하는 아래에 있습니다.

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

이 호출은 토글 된 상태를 다시 반영하는 mapDispatchToProps 함수 아래로 이동합니다.

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

감사합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.