🚩 목표
☑️ setState 최적화
☑️ state 정합성 체크
☑️ 백스페이스 키 활성화
💡 setState 최적화
- 현재 상태와 나중 상태를 비교하는 함수.
- 만약 두 상태가 같다면 setState 함수를 return해 render까지 일어나지 않도록 함.
- ex) 같은 경로(문자열)을 setState할 경우 render할 필요 없음.
onClick: async (id) => { //클릭한 경로 외에 paths를 날려줌. const currentPaths = this.state.paths; if (id) { const pathIndex = currentPaths.findIndex((path) => path.id === id); const nextPaths = currentPaths.slice(0, pathIndex + 1); if (currentPaths.length === nextPaths.length) { return; } this.setState({ ...this.state, paths: nextPaths, }); } else { if (currentPaths.length === 0) { return; } this.setState({ ...this.state, paths: [], }); } await fetchNodes(id); },
- 호출이 두 번에서 한 번으로 줄음.
과연 length로 판별하는 게 맞을까?
✔️ state 정합성 체크
- 각 컴포넌트마다 올바른 state가 들어왔는지 확인함.
Array.isArray()
로 배열이 들어왔는지 판별함.
- 배열 안 여러 객체가 들어가 있는 경우
forEach
로 순회하며 각 type을 확인함. if문을 사용하지 않고 forEach를 순회하면 빈배열에 대한 예외처리 가능.
this.validateState = state => { if (!Array.isArray(state)) { throw new Error("state must be Array"); } state?.forEach(path => { if (typeof path.id !== "string") { throw new Error('id must be a string'); } if (typeof path.name !== "string") { throw new Error('name must be a string'); } if (typeof path.type !== "string") { throw new Error('type must be a string'); } }) }
API에서 id 값을 string으로 내려줄 때 validate를 string으로 해야할까? number로 해야할까?
빈 배열에
evey
를 사용하면 true를 return함.◀️ 백스페이스 키 활성화
window.addEventListener("keydown", (e) => { if (e.key === "Backspace") { onPrevClick(); } });
- addEventListener의 keydown으로
Backspace
가 입력될 경우onPrevClick
을 호출함.
onPrevclick
은 nextPaths의 마지막을pop
한 경로로 setState함.
- 이때 로딩중이거나 root일 경우 반환하는 방어코드를 작성함.
onPrevClick: async () => { const nextPaths = [...this.state.paths]; nextPaths.pop(); this.setState({ ...this.state, paths: nextPaths, }); if (this.state.isLoading) { return; } if (nextPaths.length === 0) { await fetchNodes(); } else { await fetchNodes(nextPaths[nextPaths.length - 1].id); } }, });