개발자

react, rn 리스트 엔트리 구현시 원본 리스트를 수정하는 함수 최적화가 고민됩니다..

5월 5일조회 76

리스트 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일

그냥 의사 코드 정도니까, 원래 사용 목적에 맞게 변경하셔야 합니다!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!