개발자
리스트 A 엔트리 컴포넌트 B A를 수정하는 함수 C 이렇게 있을 때 B에서 A를 수정해야 하는 상황입니다. 모바일 환경이라 최대한 엔트리 B를 최적화 하고 싶은데 memo를 해야할 때 함수C는 어떻게 최적화 해야할까요 A에 선언하면 A의 최신 값을 얻기 위해 C가 변경될 때 마다 B또한 C의 변경에 의해 재렌더링 될 것이니 기존에는 이런 재렌더링을 막기위해 setA( (prevA) => { ... } ) 와 같은식으로 setA 내부의 callback으로 A의 최신값을 사용해서 A를 C의 의존성 배열에 추가하는 것을 피해왔는데 수정시 api의 res data를 사용할 일이 생기니 setState내에서는 async await 사용이 불가능해서 질문드립니다... 바보같은 저에게 단비 같은 가르침을 내려주세요..
답변 1
스무스하게 하시려면 외부 상태 라이브러리나 useReducer를 쓰는게 좋습니다. 굳이 props로 넘기는 방식으로 만든다 그러면 아래와 같은 방향으로 구현하면 좋을듯 합니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
"use client"; import { Dispatch, Fragment, RefObject, SetStateAction, useRef, useState, useCallback, } from "react"; type MyListData = RefObject<string[] | null>; const RenderingRef = () => { const list = useRef<string[] | null>(["this", "is", "data"]); const changeFunctionC = useCallback( // 비동기 작업 아무거나 async (list: MyListData, setAction: Dispatch<SetStateAction<boolean>>) => { let newList: string[] = []; if (list.current) { newList = [...list.current, "추가"]; } //.. start await list.current = newList; console.log("🚀 ~ changeFunctionC ~ current:", list.current); //.. end await // 새로운 데이터 랜더링하도록 전파, 함수 변경과는 상관없음 setAction((prev) => !prev); }, [] ); console.log("Parent Rendered"); return ( <div> <h2>Ref를 사용해 보자</h2> <YourCompB list={list} changeFunctionC={changeFunctionC} /> </div> ); }; type YourCompBProps = { list: MyListData; changeFunctionC: (list: MyListData, setAction: Dispatch<SetStateAction<boolean>>) => void; }; const YourCompB = ({ list, changeFunctionC }: YourCompBProps) => { const [isChanged, setIsChanged] = useState(false); console.log("값 바뀌었데~ , isChanged: ", isChanged); console.log("Child Rendered"); if (!list.current || list.current.length === 0) return ( <> <p>데이터 없어용~</p> </> ); return ( <> {list.current.map((item, index) => { return ( <Fragment key={index}> <p className="text-white">{item}</p> </Fragment> ); })} <button onClick={() => { changeFunctionC(list, setIsChanged); }} > 조작버튼 </button> </> ); }; export default RenderingRef;
포크코딩
별빛상단 단주 • 5월 5일
그냥 의사 코드 정도니까, 원래 사용 목적에 맞게 변경하셔야 합니다!
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
지금 가입하면 모든 질문의 답변을 볼 수 있어요!