[React] 배열 데이터 처리(생성,렌더링, 수정,제거)

728x90
반응형

* velopert.com/3636 velopert.com/3638공부하며 필요한 부분 메모한 글입니다

 

배열에 데이터를 추가할 때 push메소드를 쓰듯이 this.state.array.push('value'); 로 하면 안된다.

리액트에서는 내부 값을 직접적으로 수정하면 안된다 (불변성 유지)

 

push,splice,unshift,pop은 기존 배열 자체를 수정하므로 쓰지 않는 것을 권장한다(state를 건든다면)

대신 새 배열을 만들어내는 함수인 concat, slice, map, filter와 같은 함수를 사용할 수 있다.

 

불변성 유지를 하는 이유는 리액트에서 모든 것들이 필요한 상황에 리렌더링 되도록 할 수 있고 성능도 최적화할 수 있기 때문이다. 

const array = [1,2,3,4];
const sameArray = array;
sameArray.push(5);

console.log(array !== sameArray); // false

불변성을 유지하지 않으면 같은 배열을 가르키는 레퍼런스가 만들어져서 같은 배열을 가르켜 비교할 수 없다.

객체도 마찬가지이다.

 

배열 데이터 추가하기

 this.setState({
      information: information.concat({ id: this.id++, ...data })
    })
    
    //함수형
    setInformation(information.concat({id:this.id++,...data}))

 

배열 데이터 렌더링

 

원문의 컴포넌트를 함수형으로 고쳤다. 자식 컴포넌트에 각각의 데이터를 전달하여 렌더링할 수 있다.

key값은 필수로 지정해야 한다. 배열이 undefine일 경우를 대비해 defaultProps를 설정해 예외처리를 해준다.

const PhoneInfoList =({data})=> {

    const list = data.map(
      info => (<PhoneInfo key={info.id} info={info}/>)
    );

    return (
      <div>
        {list}    
      </div>
    );
  }

PhoneInfoList.defaultProps = {
    data: []
  }

export default PhoneInfoList;

 

key를 부여하지 않을 경우 

배열의 index가 key값으로 설정된다

<div key={0}>A</div>
<div key={1}>B</div>
<div key={2}>C</div>
<div key={3}>D</div>

 

문제점

중간에 데이터가 추가될 경우 밑의 데이터도 줄줄히 index가 변경되어 key값이 바뀐다.

추가적인 dom연산을 하게 되므로 비효율적이다.

<div key={0}>A</div>
<div key={1}>B</div>
<div key={2}>X</div> [C -> X]
<div key={3}>D -> C</div> [D -> C]
<div key={4}>D</div> [새로 생성됨]

하지만 고유값을 준다면 새로 추가된 부분만 새로 dom에 추가되고 나머지는 그대로 유지된다.

key값은 언제나 고유해야한다.

<div key={0}>A</div>
<div key={1}>B</div>
<div key={5}>X</div> [새로 생성됨]
<div key={2}>C</div> [유지됨]
<div key={3}>D</div> [유지됨]

데이터 제거

filter함수 사용

 handleRemove = (id) => {
    setInformation({
      information: information.filter(info => info.id !== id)
    })
  }
  
  PhonoeList.defaultProps = {
    list: [],
    onRemove: () => console.warn('onRemove not defined'),
  }

 

const PhoneInfo =({info,onRemove})=> {
	const handleRemove=()=>{
    onRemove(info.id)
    }


  return (
      <div style={style}>
        <div><b>{info.name}</b></div>
        <div>{info.phone}</div>
        <button onClick={handleRemove}>삭제</button>
      </div>
    );
  }

export default PhoneInfo;

배열 데이터 수정

 

  const handleUpdate = (id, data) => {

    setInformation({
      information: information.map(
        info => id === info.id
          ? { ...info, ...data } // 새 객체를 만들어서 기존의 값과 전달받은 data 을 덮어씀
          : info // 기존의 값을 그대로 유지
      )
    })
  }

 

728x90
반응형
TAGS.

Comments