// 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. 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를 사용해서 데이터를 변경하니 자동으로 렌더링까지 됨