일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 리스트 렌더링
- Spacer
- git 같은계정 다른 컴퓨터
- KDT 프로그래머스 데브코스 프론트엔드
- SCSS use
- SCSS extend
- vuex map
- 다른컴퓨터에서 git사용
- 리액트
- KDT 프로그래머스
- nextjs사용법
- react next
- flex
- 프로그래머스 데브코스
- netlify redirect
- vue mixin
- vue 이벤트 수신
- 프로그래머스 데브코스 프론트엔드
- 프로그래머스 K_Digital Training
- 쌓임맥락
- 고양이 사진 검색기
- Vue
- 이벤트 수식어
- intersection opserver
- SCSS forward
- postcss
- 폼 입력 바인딩
- vue 지역 컴포넌트
- 프로그래머스 프론트엔드 데브코스
- SCSS import
- Today
- Total
혼자 적어보는 노트
[React] 비동기 setState 연속 처리 시 오류 본문
react에서 state를 변경하기위해
this.setState나 useState에서 setState를 사용하게 되는데
비동기적으로 업데이트되는 특성 때문에 종종 원하지 않는 결과를 보여줄 때가 있다.
setState를 동기적으로 호출하기 위해
this.setState의 두번 째 인자에 콜백 함수를 넣어 동기적으로 실행하게 하거나
useState와 useEffect를 사용하여 setState가 실행된 후를 감지할 수는 있으나
개별적으로 나누어진 함수 안에서 state를 함께 변경 할때
state변경하기가 어려웠다.
아래의 코드는 직접 문제를 겪게된 코드이다.
const addHistory = (keyword) => {
if (!keyword) {
return;
}
const hasHistory = historyList.some((item) => item.keyword === keyword);
if (hasHistory) removeHistory(keyword);
// history에 중복된 값이 있다면 history를 지우는 함수 실행
const history = { id: createNextId(historyList), keyword };
setHistoryList([history, ...historyList]); //* 문제발생 부분 1
};
const removeHistory = (keyword) => {
const history = historyList.filter((item) => item.keyword !== keyword);
// keyword로 받은 값이 중복된다면 제거후 새로운 object로 반환
setHistoryList(history); //* 문제발생 부분 2
};
addHistory라는 함수 안에서 hasHistory로 중복된 keyword확인 후 값이 있다면
removeHistory를 실행해서 값을 지우고 새롭게 history를 상단에 추가하는 기능을 구현하고자 했다.
하지만 removeHistory에서 실행된 setHistoryList()의 실행이 되지 않고
addHistory에서 실행한 SetHistoryList()만 실행이 되는 것이다.
즉 값이 지워지지 않은 상태에서 추가만 되는 상황이다.
[해결방법]
setState사용시 이전 state를 인자로 받고 새로운 state반환
const addHistory = (keyword) => {
// .. 생략
if (hasHistory) {
removeHistory(keyword);
}
const newHistory = { id: createNextId(historyList), keyword };
setHistoryList((historyList) => [newHistory, ...historyList]);
//prevState를 인자로 받고 새로운 state를 반환해준다
};
const removeHistory = (keyword) => {
const history = historyList.filter((item) => item.keyword !== keyword);
setHistoryList(history);
// 해당 Setstate먼저 실행
};
위와 같이 setState에 함수를 인자를 넣어서 실행 시
원하는대로 removeHistory()로 값이 지워진 후 addHistory()의 setHistoryList가 실행되었다.
이것으로 알게된 사실은
함수형 setState()에는 이전의 state를 인자로 받고 새로운 state 객체를 반환할 수 있다는 것이다.
const [test, setTest] = useState(0);
const testClick = () => {
setTest(test + 1);
setTest(test + 2);
setTest(test + 3);
};
// 연속된 setState로 merge되어
// test에는 맨 하단의 변경 값인 3이 저장된다
const testClick = () => {
setTest((prevState) => prevState + 1);
setTest((prevState) => prevState + 2);
setTest((prevState) => prevState + 3);
};
// 이전의 state를 참조하게 되어 test에는 6의 값이 저장된다
'React' 카테고리의 다른 글
[React] 오늘 하루 안보기/ 24시간 동안 안보기 팝업 구현 (0) | 2021.12.20 |
---|---|
[React] input warning / defaultValue / readOnly (0) | 2021.12.17 |
[React] input focus감지 / 영역 밖 클릭 시 이벤트 (0) | 2021.12.14 |
[React] key를 사용해야하는 이유 (0) | 2021.12.13 |
[React] 비동기 SetState 동기식 처리 (0) | 2021.12.10 |