리액트에서 리덕스의 list로 컴포넌트 그리기

Tony·2021년 8월 31일
0

react

목록 보기
22/86
post-custom-banner
  1. 컴포넌트에 list 자체를 전달해서 컴포넌트 안에서 처리 하는 방법
  • 좋지 않음 : 기존에 설정된 값들(store read-only 속성제거)을 변경해야 함(방금 작업한 코드)
// course_info.tsx
const [textArray, setTextArray] = useState<string[]>();
<TextListBox list={textArray} setTextArray={setTextArray} />;

// TextListBox.tsx
type Prop = {
  list?: string[];
  setTextArray: React.Dispatch<React.SetStateAction<string[] | undefined>>;
};

const TextListBox = ({ list = [], setTextArray }: Prop) => {
  const onClickDelete = (textList: string[], index: number) => {
    textList.splice(index, 1);
    setTextArray([...textList]);
    console.log('after remove', textList);
  };

  return (
    <button onClick={() => onClickDelete(list, index)} type="button">
      <DeleteIcon />
    </button>
  );
};
  1. 컴포넌트 밖에서 array.map() 을 사용해서 그리기 : good
  • redux에서 read-only로 설정한 것을 해치지 않으면서 강제로 re-rendering을 위해 useState를 억지로 사용하지 않아도 된다.
  • 단, 각 경우에 맞게 dispatch를 다르게 날려서 원하는 데이터가 변경된 것을 반영하도록 해줘야 한다.
1. read-only의 불변성 보장
// course_info.tsx -> 재사용 컴포넌트의 부모 컴포넌트에서 map을 사용
// 대신 onClick 을 전달
	<ul>
          {lectureData?.courseInfo.whatYouCanLearn.map((item, index) => (
            <TextListBox
              key={index}
              item={item}
              onClick={() => onClickTextBoxDelete(lectureData?.courseInfo.whatYouCanLearn, index, 'whatYouCanLearn')}
            />
          ))}
        </ul>

  const onClickTextBoxDelete = (
    textList: string[],
    index: number,
    boxType: 'whatYouCanLearn' | 'expectedStudents' | 'requiredKnowledge'
  ) => {
    // textList.splice(index, 1); // slice를 사용해서 기존의 read-only를 해치지 않게 해야 함
    const textArray = [...textList];
    textArray.splice(index, 1);
    // dispatch() 각각 다르게 만들어서 사용
    switch (boxType) {
      case 'whatYouCanLearn':
        dispatch({
          type: DELETE_ITEM_WHATYOUCANLEARN,
          data: textArray,
        });
        break;
      case 'expectedStudents':
        break;
      case 'requiredKnowledge':
        break;
      default:
        console.error('boxType is wrong');
    }

    console.log('after remove', textList);
  };

1방식에서 list를 직접 전달할 땐 불변성을 지키지도 않고 redux store의 값을 직접 변경했지만
2번 방법에서 불변성을 지키고 reducer를 사용해서 데이터를 변경하니 자동으로 렌더링까지 됨

결론

  • 재사용 컴포넌트엔 list를 전달하기 보단 그 부모 컴포넌트에서 list의 map method를 이용하여 컴포넌트를 재사용하는 것이 올바른 방법이다.
profile
움직이는 만큼 행복해진다
post-custom-banner

0개의 댓글