ag-grid 라이브러리를 사용하다가 발생한 문제. 새로운 행을 생성해서 바로 그 셀에 포커스(focus, edit 둘 다)를 줘야 했다.
const addNewRow = () => {
setRowData((prev) => [
{ id: 300, userId: 300, name: null, body: null },
...prev,
]);
editNewRow();
};
const editNewRow = () => {
gridRef.current.api.ensureIndexVisible(0); // 첫 행으로 스크롤 이동
gridRef.current.api.setFocusedCell(0, "name");
gridRef.current.api.startEditingCell({
rowIndex: 0,
colKey: "name",
});
};
처음에는 이렇게 했는데 동작하지 않았음. 행을 두번째 추가할 때 부터 동작이 되었다.
여기서 state 업데이트는 비동기적이라는것이 떠올라서 해결방법을 서치했음. -> 리액트 새 공식문서
의 state 관련된 부분들을 학습하면 크게 도움이 된다.
위의 문제를 해결하는 방법에는 setTimeout을 사용하는 방법과 리액트18에서 새롭게 제공하는 flushSync를 사용하는 방법이 있다.
useEffect를 사용해서 rowData가 변경되면 새로운 행을 직접 만든것인지 체크하는 조건문을 추가하고 editNewRow 함수를 실행시켜주어도 되겠지만 가장 나쁜 방법이라고 생각했음. 일단 1. 복잡함 2. 의존성이 생기고 3. addNewRow 함수 밖에서 코드를 작성해야 하니 가독성도 해친다.
// setTimeout 사용방법
const addNewRow = () => {
setRowData((prev) => [
{ id: 300, userId: 300, name: null, body: null },
...prev,
]);
setTimeout(() => {
editNewRow();
}, 0);
};
동기적인 동작이 모두 실행되고 나서 state가 업데이트 되는데, 그렇다면 큐에는 state 업데이트 작업 하나가 있을 것이다.
여기서 editNewRow를 setTimeout을 통해 비동기 작업으로 만들어준다면 이 함수도 큐에 들어가서 state 업데이트 다음에 실행되게 된다
setTimeout을 0초로 둔다고 해도 사실은 4ms의 딜레이가 발생한다. 특정 동작을 비동기적으로 만들 때 자주 사용하는 기법이라는 것은 들었는데 그때는 전혀 이해가 안가다가 직접 사용해보니 이해가 되었다.
// flushSync 사용방법
const addNewRow = () => {
flushSync(() => {
setRowData((prev) => [
{ id: 300, userId: 300, name: null, body: null },
...prev,
]);
});
editNewRow();
};
flushSync는 리액트 18에서 새로 등장한 API이다. state 업데이트를 동기적으로 실행시킬 수 있다. 그래서 위 코드는 setRowData가 먼저 실행되고, 그 다음 editNewRow가 실행된다. 비동기와 setTimeout에 대한 이해가 없어도 사용할 수 있는 방법이지만 아래의 사진처럼 공식문서에서는 성능에 영향을 줄 수 있다고 경고하고 있다.
챗봇 비스무리한걸 구현할 때도 동일한 문제가 발생했는데 위의 경험이 있어서 바로 해결할 수 있었음.
타이핑이 끝났다는것을 알리기 위해 isTyping이라는 상태를 변경하고 바로 textarea창에 포커스를 주는 흐름인데 isTyping은 가장 마지막에 업데이트 될테니 당연히 동작하지 않는다.
setTimeout으로 focus의 실행 순서를 더 뒤로 미뤄줬더니 포커스가 제대로 동작했다.
다른 방법이 있을지도...?? 생각지도 못한 더 좋은 방법이 있을지도..... ~~
'문제 기록' 카테고리의 다른 글
[react query] useQuery의 enabled와 isLoading (0) | 2023.06.24 |
---|---|
[framer-motion] 줄 당기는 효과 만들기 (0) | 2023.06.24 |
[tanstack-query] invalidateQueries를 사용해도 업데이트가 되지 않는 문제 (0) | 2023.02.27 |
''ts-node'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는배치 파일이 아닙니다. 해결방법 (0) | 2023.02.13 |
[git] 변경 사항 다른 브랜치에 커밋하기 (0) | 2022.11.19 |
댓글