컴포넌트 반복

Haechan Kim·2022년 1월 9일
0

React

목록 보기
6/13

리액트에서 코드가 반복될 때 효율적으로 관리하는 법

  • map() 함수
    map은 파라미터로 전달된 함수를 사용해 원하는 규착에 따라 변환 후 새로운 배열 생성
  • map의 파라미터
    • 콜백 함수
    • currentValue: 현재 처리하고 있는 요소
    • index: 현재 처리하고 있는 요소의 index 값
    • array: 현재 처리하고 있는 원본 배열
    • thisArg(선택 항목): callback 함수 내부에서 사용할 this 레퍼런스
let arr = [1,2,3,4,5];
let newArr = arr.map(function(num) {
  return num*num;
}
// ES6 문법
let newArr2 = arr.map(num => num*num);
console.log(newArr); // [1,4,9,16,25]

같은 원리로 기본 배열로 컴포넌트로 구성된 배열을 생성할 수 있다
이 코드를

const IterationSample = () => {
    return (
      <ul>
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
      </ul>
    );
  };

다음과 같이 바꿀 수 있다

const IterationSample = () => {
    const names = ['a', 'b', 'c', 'd']; // 문자열로 구성된 배열 선언
    // <li>...</li> 로 된 배열 새로 생성하고 nameList에 담는다
    const nameList = names.map(name => <li>{name}</li>); 
    return <ul>{nameList}</ul>
}

map함수에서 JSX작성할 때 DOM요소로 작성해도 되고 컴포넌트 사용해도 됨

실행은 되지만 개발자 도구에서 "key" prop이 없다는 경고 메시지 표시

  • key
    리액트에서 key은 컴포넌트 배열 렌더링 했을 때 어떤 원소의 변동 있었는지 알아내려고 사용
    key 없을 때는 리스트 순차적으로 비교
    어떤 변화 일어났는지 빠르게 알아냄 (원소 생성, 제거, 수정 등)

  • key 설정
    map함수의 인자로 전달되는 콜백 함수 내부에서 컴포넌트 props 설정하듯 하면 됨
    key 값은 유일해야 함. 데이터의 고유 값 또는 index(index는 고유한 값 없을때만. 인덱스를 키로 사용하면 배열 변경될 때 리렌더링 효율적이지 못함)

const IterationSample = () => {
    const names = ['a', 'b', 'c', 'd'];
    // 인덱스를 key로. 경고 메세지 안뜸
    const nameList = names.map((name, index) => <li key = {index}>{name}</li>);
    return <ul>{nameList}</ul>
}
  • 동적인 배열 렌더링 하기
    useState 사용해 상태 설정 (3가지 상태)
    • 데이터 배열
    • 텍스트 입력 input의 상태
    • 데이터 배열에서 새로운 항목 추가할 때 사용할 고유 id

이전엔 단순히 문자열로 이뤄진 배열을 만들었지만 이번엔 객체 형태로 이뤄진 배열을 만든다
해당 객체에는 문자열과 고유 id값이 있다

const IterationSample = () => {
    const [names, setNames] = useState([
        {id:1, text: 'aa'},
        {id:2, text: 'bb'},
        {id:3, text: 'cc'},
        {id:4, text: 'dd'},
    ]);

    const [inputText, setInputText] = useState('');
    const [nextId, setNextId] = useState(5); // 새로운 항목 추가할때 사용할 id
    // map함수 사용 시 key값을 index 대신 name.id로 지정
    const nameList = names.map(name=> <li key = {name.id}>{name.text}</li>);
    return <ul>{nameList}</ul>
}
  • 데이터 추가 기능 구현
import React, {useState} from 'react';

const IterationSample = () => {
    const [names, setNames] = useState([
        {id:1, text: 'aa'},
        {id:2, text: 'bb'},
        {id:3, text: 'cc'},
        {id:4, text: 'dd'},
    ]);

    const [inputText, setInputText] = useState('');
    const [nextId, setNextId] = useState(5); // 새로운 항목 추가할때 사용할 id
    
    const onChange = e => setInputText(e.target.value); // inputText값을 input에 입력한 값으로 변경
    
    const onClick = () => {
        const nextNames = names.concat({ // names에 새로운 원소 추가 후 반환
            // push 대신 concat사용한 이유는 불변성 유지해 성능 최적화 위해
            id: nextId, // id값은 nextId로
            text: inputText
        });

        setNextId(nextId + 1);
        setNames(nextNames); // names값 업데이트
        setInputText (''); // inputText를 비움

    }

    // map함수 사용 시 key값을 index 대신 name.id로 지정
    const nameList = names.map(name=> <li key = {name.id}>{name.text}</li>);
    return (
        <>
            <input value = {inputText} onChange = {onChange} />
            <button onClick = {onClick}>추가</button>
            <ul>{nameList}</ul>
        </>
    )
}

export default IterationSample;
  • 데이터 제거 기능 구현
    항목 더블클릭 시 삭제
    불변성 유지하면서 업데이트 해야 함
    ㄴ 배열 내장 함수 filter 사용
...
const onRemove = id => {
    // filter 이용해 더블클릭한 id 삭제
    const nextNames = names.filter(name => name.id !== id); 
    setNames(nextNames);
};

// map함수 사용 시 key값을 index 대신 name.id로 지정
const nameList = names.map(name => <li key = {name.id} 
// 더블클릭 시 onRemove()
onDoubleClick = {() => onRemove(name.id)}>{name.text}</li>);
return (
    <>
        <input value = {inputText} onChange = {onChange} />
        <button onClick = {onClick}>추가</button>
        <ul>{nameList}</ul>
    </>
)
  • 정리
    key값은 언제나 유일해야 함
    배열 변형할때 배열에 직접 접근해 수정 X
    concat, filter 등 배열 내장 함수 이용해 새로운 배열 만들고 수정
    불변성

0개의 댓글