반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

동적으로 Input 추가, 삭제하기 본문

리액트

동적으로 Input 추가, 삭제하기

5_hyun 2022. 12. 23. 03:54
반응형

필요한 변수 및 interface

interface ItemInfo {
  id: number;
  name: string;
  values: string;
}

TypeScript라서 우선 데이터의 구조를 잡아줬다.

  const ItemId = useRef(1);
  const [itemInfos, setItemInfos] = useState<ItemInfo[]>([
    { id: 0, name: "", values: "" },
  ]);

ItemId는 input이 동적으로 늘어감에 따라 각 Item에 부여할 ID이다.

itemInfos는 각 아이템들을 저장하는 배열이다.

필요한 함수들

input 추가 함수

  const addInput = useCallback(() => {
    const Item = {
      id: ItemId.current,
      name: "",
      values: "",
    };

    setItemInfos([...itemInfos, Item]);
    ItemId.current++;
  }, [itemInfos]);

Item에 id와 데이터를 초기화한다. 그리고 setItemInfos를 이용해서 itemInfos를 최신화한다.

다음 추가될 input을 위해서 ItemId의 값을 1 올려놓는다.

input 삭제 함수

  const deleteInput = useCallback(
    (index: number) => {
      setItemInfos(itemInfos.filter((item) => item.id !== index));
    },
    [itemInfos]
  );

input의 삭제는 filter함수를 이용해서 구현하였다.

값을 변경하는 함수

  const onChangeItemName = useCallback(
    (e: ChangeEvent<HTMLInputElement>, index: number) => {
      let temp = [...itemInfos];
      temp.find((v, idx) => {
        if (v.id === index) {
          temp[idx].name = e.target.value;
        }
      });

      setItemInfos(temp);
    },
    [itemInfos]
  );

  const onChangeItemValues = useCallback(
    (e: ChangeEvent<HTMLInputElement>, index: number) => {
      let temp = [...itemInfos];
      temp.find((v, idx) => {
        if (v.id === index) {
          temp[idx].values = e.target.value;
        }
      });

      setItemInfos(temp);
    },
    [itemInfos]
  );

values와 name의 값을 변경하는 함수들이다. 변수의 이름만 다를 뿐 코드가 같다.

index 매개변수로 어떤 id의 name 혹은 value를 바꿀지 받는다. 그리고 temp에 itemInfos를 넣어주고 temp에서 값을 변경한다. 이때 find를 이용해서 temp에서 입력받은 index와 같은 id를 가진 객체를 찾고 값을 변경해주었다.

화면에 데이터 보여주는 코드

{itemInfos.map((item) => {
  return (
    <div key={item.id}>
      <input
        type="text"
        value={item.name}
        onChange={(e) => {
          onChangeItemName(e, item.id);
        }}
      />
      <input
        type="text"
        value={item.values}
        onChange={(e) => {
          onChangeItemValues(e, item.id);
        }}
      />
      <button onClick={() => deleteInput(item.id)}>-</button>
    </div>
  );
})}

map 함수를 사용해서 데이터를 출력했다. map 함수에서 가장 주의해야 하는 것은 배열이 수정, 삭제 등 변경되는 경우에는 key를 절대 그냥 index로 해주면 안된다. 그렇기에 나는 item.id를 key로 주었다. 그리고 각 태그들에 위에서 작성한 함수를 넣어줘서 input을 동적으로 추가, 삭제하는 코드를 만들 수 있었다.

느낀점

위 코드들은 동적 input을 위한 아주 기본적인 코드들이다. 이 코드를 활용하여 Item 개수 제한이나 input에 값을 입력하는 글자 수 제한을 줄 수 있을 것이다.

막상 보면 별거 없는 코드이지만 나는 input를 동적으로 추가하고 삭제하는 코드를 구현하기까지 꽤 오랜 시간이 걸린 것 같다. 많이 부족함을 느꼈고 모든 만들 수 있는 개발자가 되기 위해서 더 공부하고 기록해야겠다.

반응형

'리액트' 카테고리의 다른 글

styled-component에서 global style  (0) 2022.12.24
react-slick(이미지 슬라이드)  (1) 2022.12.24
input으로 파일 업로드 구현  (0) 2022.12.20
map 함수 사용시 주의할 anti-pattern(key)  (0) 2022.12.20
autosize  (0) 2022.12.20
Comments