상태를 업데이트하지 않는 React setState


91

그래서 나는 이것을 가지고 있습니다.

let total = newDealersDeckTotal.reduce(function(a, b) {
  return a + b;
},
0);

console.log(total, 'tittal'); //outputs correct total
setTimeout(() => {
  this.setState({dealersOverallTotal: total});
}, 10);

console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); //outputs incorrect total

newDealersDeckTotal은 숫자의 배열 일뿐입니다. [1, 5, 9]예를 들어 this.state.dealersOverallTotal정확한 합계를 제공하지는 않지만 그렇 total습니까? 이것이 문제가 해결되었는지 확인하기 위해 시간 초과 지연을 설정했습니다. 명백한 것이 있습니까 아니면 더 많은 코드를 게시해야합니까?



@Assan 건배 !!

답변에서 말한 것 외에도을 호출 하기 전에 상태 값을 명시 적으로 기록하고 있습니다 setState.
Felix Kling

1
@FelixKling 아니 나는 그것을 설정 한 후 this.state를 호출 하고 있습니다. 전에 변수를 로깅하고 있습니다. 아니?

시간 초과로 인해 setState상태를 기록한 후에 실제로 실행됩니다. 디버깅에서 의도 한 것은 console.log타임 아웃 내부와 setState외부에 파트를 넣는 것이라고 생각합니다 .
Fabian Schultz

답변:


181

setState()일반적으로 비동기식입니다. 즉 console.log, 상태가 아직 업데이트되지 않은 상태입니다. setState()메소드 의 콜백에 로그를 넣으십시오 . 상태 변경이 완료된 후에 실행됩니다.

this.setState({ dealersOverallTotal: total }, () => {
  console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
}); 

1
그 외에도 OP는 호출 하기 전에 상태 값을 명시 적으로 기록합니다 setState.
Felix Kling

이것은 나에게도 효과적입니다. 과거에는 이것을 사용했습니다.`this.setState ({someVar : newValue}, function () {console.log ( "force update}); '하지만 어떤 이유로 걱정하지 않았습니다 내가 코드를 업데이트 할 때 작동 이상 더 이상 같은 설명 어떤 생각이 왜.?
Jozcar

@Jozcar 구문은 오른쪽 (괄호 누락)되지도 작동합니다 :this.setState({someVar: newValue},function(){ console.log("force update") });
파비안 슐츠

imgur.com/Ku0OjTl 이 문제를 해결하려면 어떻게해야하는지 알려주세요.
Johncy

useState기능 구성 요소에서 후크 를 사용하는 경우 작동하지 않습니다 . useEffect렌더링 후 효과에 대신 사용하십시오 .
Hasan Sefa Ozalp

16

setState는 비동기입니다. 콜백 메서드를 사용하여 업데이트 된 상태를 가져올 수 있습니다.

changeHandler(event) {
    this.setState({ yourName: event.target.value }, () => 
    console.log(this.state.yourName));
 }

10

async / await 사용

async changeHandler(event) {
    await this.setState({ yourName: event.target.value });
    console.log(this.state.yourName);
}

나도 똑같이하고있다. 나를 위해 일함
prodeveloper

8

setState()작업은 비동기 따라서 당신은 console.log()전과 실행됩니다 setState()변이 값을 따라서 당신은 결과를 참조하십시오.

이를 해결하려면 setState()다음과 같이 의 콜백 함수에 값을 기록하십시오 .

setTimeout(() => {
    this.setState({dealersOverallTotal: total},
    function(){
       console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
    });
}, 10)

JavaScript는 항상 동기식입니다.
Santosh Singh

1
@santoshsingh 당신은 오해가 있습니다. API 호출, 시간 초과는 모두 비동기 적으로 발생합니다.
Shubham Khatri

위에서 언급했듯이 javascript는 비동기 적입니다. --- 올바르지 않습니다. 주로 동기식이며 경우에 따라 비동기식입니다. stackoverflow.com/questions/2035645/…
Santosh Singh

트윗 담아 가기 오, 그건 내 실수 였어. 문장을 올바르게 구성하지 않음
Shubham Khatri

콜백을 매우 영리하게 사용하여 후속 호출 전에 상태가 업데이트되도록합니다!
user1204214 2016

5

후크의 경우 후크를 사용해야합니다 useEffect.

const [fruit, setFruit] = useState('');

setFruit('Apple');

useEffect(() => {
  console.log('Fruit', fruit);
}, [fruit])

좋습니다. useEffect와 함께 작동합니다. 하지만 왜 필요합니까?
alex351

useEffect다시 렌더링 할 때마다 실행되며 배열에 전달 된 항목이 상태 변수 인 경우 변경됩니다. 따라서 과일이 변경되고 구성 요소가 다시 렌더링되면 해당 useEffect가 실행됩니다.
Siraj Alam

useEffect 외부에서 setFruit 및 console.log fruit를 실행했는데 변경되지 않습니다. : /
alex351

3

setstate는 반응에서 비동기식이므로 콘솔에서 업데이트 된 상태를 보려면 아래와 같이 콜백을 사용하십시오 (콜백 함수는 setstate 업데이트 후 실행됩니다).

여기에 이미지 설명 입력

아래 방법은 "권장되지 않음"이지만 이해를 돕기 위해 상태를 직접 변경하면 다음 줄에서 업데이트 된 상태를 볼 수 있습니다. 나는 이것을 "권장하지 않음"을 반복한다

여기에 이미지 설명 입력


감사합니다. 변수를 직접 설정해야합니다
notacorn


0

반응 상태를 여러 번 설정할 때 문제가 발생했습니다 (항상 기본 상태 사용). 이 반응 / github 문제에 따라 저에게 효과적 이었습니다.

const [state, setState] = useState({
  foo: "abc",
  bar: 123
});

// Do this!
setState(prevState => {
  return {
    ...prevState,
    foo: "def"
  };
});
setState(prevState => {
  return {
    ...prevState,
    bar: 456
  };
});

0

나는 복잡한 코드로 같은 상황을 겪었고 기존 제안에서 아무것도 효과가 없었습니다.

내 문제는 setState구성 요소 중 하나에서 발행 한 콜백 func에서 발생했습니다. 그리고 내 의심스러운 것은 호출이 동기식으로 발생하여 setState상태를 전혀 설정 하지 못했다 는 것입니다.

간단히 말해서 다음과 같은 것이 있습니다.

render() {
    <Control
        ref={_ => this.control = _}
        onChange={this.handleChange}
        onUpdated={this.handleUpdate} />
}

handleChange() {
    this.control.doUpdate();
}

handleUpdate() {
    this.setState({...});
}

내가 그것을 "고쳐야"하는 방법은 doUpdate()다음 setTimeout과 같이 넣는 것이었다 .

handleChange() {
    setTimeout(() => { this.control.doUpdate(); }, 10);
}

이상적이지는 않지만 그렇지 않으면 상당한 리팩토링이 될 것입니다.

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