본문 바로가기
tech documents/react

setState 이후 업데이트 된 상태를 사용하지 못하는 이유.

by kimtahen 2020. 7. 16.
반응형

1. 

아래의 코드의 문제점을 찾아보자. 

const [items, setItems] = useState([]);
const onClickEvent = (text) => () => {
    console.log('called')
    if (text) {
        let edit = {id: uuid(), name: name, message: text}
        setItems([edit,...items]);
        const upload = async ()=>{
            console.log('upload called');
            await db.collection('chatting').doc('chatting').update({chats: items})}
        upload()
            .then(()=>{console.log('upload finished')})
            .catch((e)=>{console.log(e,'upload Error')});
        textInputRef.current.clear();
    }
}

이 코드는, 새로운 text를 받아서 state를 업데이트하고, 이 업데이트 된 상태를 데이터베이스에 업로드 하는 작업을 수행한다. 하지만 이 코드는 제대로 작동하지 않는다.

 

2.

리액트(자바스크립트) 는 위와 같은 함수가 실행될때, 모든 변수 등등의 정보를 스냅샷해서 가지고 있다고 생각하면 쉽니다. 그렇기 때문에 setItems([edit,...items]) 를 하더라도 아래의 데이터베이스 업로드 코드에서 사용하는 items 라는 상태는 새롭게 업데이트 된 상태가 아닌, 이전의 상태 값을 가지고 있게 되는 것이다. 따라서 데이터베이스에는 제대로 업로드 되지 않는다. (혹은 추정컨데, render()가 수행된 이후 새로운 상태값을 캡쳐하는 것인지도 모르겠다.) 따라서 데이터베이스는 업데이트 되지 않고, onClickEvent의 다음 호출에서 업데이트 된다. 

 

3. 

결론적으로 .update( )에 들어가야 할 코드는 state 자체인 items가 아닌, 직접 수정된 값을 넣어주어야 한다.

.update({chats: [edit,...items]})  <-- 이것이 올바른 코드이다.

반응형

댓글