본문 바로가기
React

2021.07.19 React Component 반복

by 해맑은 코린이 2021. 7. 19.

2021.07.19 React Component 반복_정리노트

 

 

오느른~~~~ 자바스크립트 map 문법 위주의 컴포넌트 반복 정리노트!

 

오늘도 리액트를 다루는 기술 6장임 ㅎㅅㅎ

 

 

map 함수

배열에서 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환!

 

arr.map(callback, [thisArg])

형태는 이렇게 쓰고, 함수니까 각각 파라미터의 역할을 정리하면, 

 

callback

새로운 배열의 요소를 생성하는 함수

 

callback 함수 파라미터

- currentValue : 현재 처리하고 있는 요소

- index : 현재 처리하고 있는 요소의 index 값

- array : 현재 처리하고 있는 원본 배열 

 

 

thisArg

callback 함수 내부에서 사용할 this 레퍼런스로 선택사항이다.

 

 

간단한 예로 콘솔에 찍어보았움.

 

 

 

이렇게 processed 는 callback 자리에 적인 num*num 를 하라는 함수의 호출 결과를 각 배열의 요소마다 적용시켜 새로운 배열로 반환되었고,

num 은 찍으면 원본 배열이 그대로! 홀홀

 

 

우리는 ES6 로 사용할거니까, 이제는 const 와 arrow function 으로 작성해서 컴포넌트 반복을 해봅씨단.

 

 

src/IterationSmaple.js ( 새로 생성 )

 

 

만약 많은  요소들이 반복된다면?? 이 때, 컴포넌트 상에서 map 을 이용해서 더 간단하게 나타낼 수 있음!

 

 

 

이렇게 리액트에서는 JSX 요소를 map 함수를 사용해서 컴포넌트를 사용해도 된다.

 

 

src/App

 

 

 

이제 App 에 렌더링하고, 실행화면을 보면,

 

 

이렇게 잘뜨는데 콘솔을 보면,

 

 

이런 에러가 떠있다. key props 가 없어요라고! 

 

리액트에서는 컴포넌트 배열을 렌더링 했을 때 어떤 원소에 변동이 있었는지 알아내려고 key를 사용한다. 

유동적인 데이터를 새로 생성하거나, 제거하거나, 수정할 수 있기 때문이지!

만약 key 가 없다면 Virtual DOM 을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화를 감지하는데, 이 때 key를 사용하면, 이 값을 사용하여 어떠한 변화가 일어나는지 빠르게 알아낼 수 있다. 

 

 

 

src/IterationSmaple.js

 

key 값을 설정할 때는 map 함수의 파라미터로 props 를 설정하듯이 적어주면 된다. key 값은 id처럼 고유해야 하므로, 데이터가 가진 고윳값을 넣는다.  ( 게시물의 번호 같은 것 )

 

여기서는 고유번호가 없기 때문에, index라는 인수를 넣어서 돌려주었다. 

 

 

그러면 이제 콘솔에서 에러를 띄우지 않는데, 고유한 값이 없을 때만 index 로 사용하자! 안그러면 배열이 변경될 때 효율적으로 리렌더링 하지 못한다.

 

 

 

 

동적인 배열 렌더링 하기

이제 호율적으로 index 를 사용하지 않고, 동적인 배열을 렌더링하기 ㄱ ㄱ

 

이제 문자열이 아닌, id 값과 내용이 담긴 객체로 설정하기.

 

 

 

이렇게 id 값을 사용해서 똑같이 만든 후에 이제 데이터를 추가하는 기능을 state 를 이용해서 만들어봅씨단.

 

 

 

총 3가지의 state 를 사용할텐데, 

 

먼저 데이터 배열이 담긴 names,

input onChange event 로 추가 데이터를 입력받을 input value 를 업데이트 할 state 인 inputText,

그 다음에 항목 추가시 id 값을 업데이트 해주는 state인  nextId!!

 

이렇게 총 3개가 필요함!

 

자 차근차근 정리하며 보자.

import React, { useState } from "react";

const IterationSample = () => {
  // 데이터 배열
  const [names, setNames] = useState([
    { id: 1, text: " 눈사람" },
    { id: 2, text: " 얼음" },
    { id: 3, text: " 눈" },
    { id: 4, text: " 바람" },
  ]);
  // input value 를 받아올 state
  const [inputText, setInputText] = useState("");

  //  고유 id 값을 위한 state
  const [nextId, setNextId] = useState(5);

  // input onChange 로 input value를 inputText state 값 업데이트
  const onChange = (e) => setInputText(e.target.value);

  // button 을 클릭했을 때 호출될 함수.
  const onClick = () => {
    // id, text 값을 업데이트 해서 names 의 데이터 배열을 업데이트
    const nextNames = names.concat({
      id: nextId,
      text: inputText,
    });
    // nextNames 즉 , 새로운 id 값과, text 를 가진 배열을 names 에 업데이트
    setNames(nextNames);
    // 배열 업데이트 하고 난 후, id값을 +1 해서 업데이트  
    setNextId(nextId + 1);
    // 마찬가지로 업데이트 한후, inputText 를 비움.
    setInputText("");
   
  };


   
 
  const nameList = names.map((name) => <li key={name.id}>{name.text}</li>);

  return (
    <div>
      {/* onChange event 시 onChange 함수 호출 */}
      <input value={inputText} onChange={onChange}></input>
        {/* onClick event 시 onClick 함수 호출 */}
      <button onClick={onClick}>추가</button>
      <ul>{nameList}</ul>
    </div>
  );
};

export default IterationSample;

 

짠 ...길지만 차근차근 보면 어려울거 없음.

 

input 에 onChange 이벤트가 일어나면 해당 함수를 호출해서 input 의 상태를 관리 한 후, 

button 을 onClick 했을 때 , concat 을 사용하여, 새로운 항목을 추가한 배열을 만들어서 setNames 를 사용해 데이터 배열을 업데이트 한다.

 

push, concat 둘 다 배열에서 새 항목을 추가할 때 쓰는 자바스크립트 함수 인데, 

 

차이점은 push 는 기존 배열에 값을 추가하여 원본 배열 자체를 바꿔버리고,

concat 은 기존 배열을 토대로 변경한 새로운 배열을 리턴한다. 

리액트에서 상태를 업데이트 할 때는 기존 상태를 그대로 두면서, 새로운 값을 사앹로 설정해야 한다. 이를 불변성 유지라 하며, 불변성 유지를 해주어야 컴포넌트의 성능을 최적화 할 수 있다.

 

 

이렇게 만약 찍어주게 되면, 

 

 

 

자! 다른 배열인지 티가 나지롱~ 원본 배열이랑 concat 으로 추가해준 배열은 서로 다르다는 걸 알 수 있다.

 

 

자 이제 실행화면 ㄱ ㄱ !

 

 

 

새로운 걸 적고 추가 버튼을 누르면 이쁘게 잘 나오고, 

 

 

console 에 nextNames 를 찍어보면, Id값도 +1 씩 잘 붙어서 들어가는것을 볼 수 있다!

 

 

자 이제 각 항목을 더블 클릭해서 지워봅씨다

 

불변성을 유지하면서, 배열의 특정 항목을 지울 때는 filter 함수를 사용.

 

이렇게 조건을 건 함수를 넣어주면, 분리 완료!

 

 

 

 

이 역시 새로운 배열로 리턴하기 때문에, 기존 배열은 불변성을 유지한다! 

 

 

이렇게 filter 함수를 사용해서 간단하게 구현할 수 있음!!

 

 

실행화면


더블 클릭을 하면, onRemove 함수가 호출되어 잘 지워지는 모습을 볼 수 있다!

 

 

 

 

참고로 저번과 같이 바로 함수를 바로 불러오면, 처음 렌더링할 때 바로 실행이 되므로 

 

 

 

 

이렇게 즉시 지워져서 값들이 나타나지 않으니, 버튼을 누른 시점 ( 이미 렌더링이 한번 되고 setNames 의 값이 설정된 시점 )  에서 작동하기 위해서는  

 

이렇게 화살표 함수로 적어줘야 잘 작동하니 잊지말기!


 

리액트 state , map, concat, filter 등을 이용해서 이렇게 유동적인 데이터들을 다루고, 반복되는 데이터를 간단히 렌더링 해보았움...! 

5장보다 그래도 덜 어려운.. 것 같아서 다행이다 ㅎ.. 오늘 포스팅 끝끝!

'React' 카테고리의 다른 글

2021.07.23 React Hooks  (0) 2021.07.23
2021.07.19 React Life Cycle  (2) 2021.07.21
2021.07.16 React ref  (0) 2021.07.16
07.13 React event handling  (0) 2021.07.14
2021.07.11 React props,state  (4) 2021.07.12

댓글