2022.10.22

GunYong·2022년 10월 22일
0

Today I Learned

목록 보기
1/15
post-thumbnail

Spread Operator

스프레드 연산자를 사용하면 배열, 문자열, 객체 등 반복 가능한 객체 (Iterable Object)를 개별 요소로 분리할 수 있습니다.

const a = {
name : ‘bok’,
age : 18
}
const age1 = 20;
const update = {…a , age :  age1} // { name : ‘bok’ , age : 20 }

update는 객체a를 ...a를 통해 복사한 후 변경하고 싶은 key값을 뒤에 써줘서 age를 age1으로 변경해주었다.

객체의 불변성

객체가 immutable 하다는 것은 객체가 최초 생성된 시점 이후 상태 값이 변하지 않는다는 것이다.

이는 state관리에 있어서 중요한 포인트이다.

리엑트에서 useState hook을 통해 state값이 객체 또는 배열인 경우 우리는 이를 직접적으로 변경해줄 것이 아니라 객체와 배열의 전체적인 부분을 새로 만들어서 업데이트를 해야지 리엑트가 페이지를 rerendering 해줄 것이다.

function a(){
const [person, setPerson] = useState({
  name: '건용',
  title: '학생',
  mentors: [
      {
          name: '홀리',
          title: '시니어개발자',
      },
      {
          name: '몰리',
          title: '시니어개발자',
      },
  ],
});
return (
<>
<button
          onClick={() => {
              const prev = prompt(`누구의 이름을 바꾸고 싶은가요?`);
              const current = prompt(`이름을 무엇으로 바꾸고 싶은가요?`);
          }}
      >
          멘토의 이름을 바꾸기
</button>
</>
)
}

버튼을 누르면 멘토의 이름을 변경해주려고 한다. 여기서 객체의 불변성의 중요성을 확인 할 수 있다.

단순하게

<button
          onClick={() => {
              const prev = prompt(`누구의 이름을 바꾸고 싶은가요?`);
              const current = prompt(`이름을 무엇으로 바꾸고 싶은가요?`);
								person.mentors[0].name = currnet;
								setPerson(person);
          }}
      >
          멘토의 이름을 바꾸기
</button>

이런식으로 변경해주면 객체는 내부에서 값이 변경되서 rerendering이 일어나지 않는다.

<button
          onClick={() => {
              const prev = prompt(`누구의 이름을 바꾸고 싶은가요?`);
              const current = prompt(`이름을 무엇으로 바꾸고 싶은가요?`);
              setPerson((a) => ({
                  ...a,
                  mentors: a.mentors.map((mentor) => {
                      if (mentor.name === prev) {
                          return { ...mentor, name: current };
                      } else {
                          return { ...mentor };
                      }
                  }),
              }));
          }}
      >
          멘토의 이름을 바꾸기
      </button>

a 라는 새로운 객체를 만들어 주었고 map을 이용해서 새로운 배열을 만들어 준 것이다.

⭐️ 혼틈 map() ⭐️

어떤 배열에 있는 요소들의 값을 변경해서 새로운 배열을 만들고 싶을 때 사용하는 배열 함수
전체적인 값을 변경해줄 수도 있고 위와 같이 spread operator을 활용하여 원하는 부분만 변경해줄 수도 있다.

⭐️ 혼틈 prompt ⭐️

변수 지정해서 prompt를 사용하면 입력값을 변수에 저장해 사용할 수 있다.

⭐️ 혼틈 객체 기본 문법, 임의의 key에 할당된 value 부르기 ⭐️

const info = {name : 'gunyong' , age : 24};

console.log(info['name']) // gunyong

useReducer

상태 업데이트 로직 분리하기

우리가 상태를 업데이트 할 때에는 useState를 사용해서 새로운 상태를 설정해주었다.

useReducer hook을 사용하면 상태 업데이트 로직을 컴포넌트 바깥에 작성 할 수 있고 다른 파일에 불러오거나 다른 파일에서 사용할 수 있다.

예로 버튼을 누르면 1증가 1감소하는 버튼을 생성해주는 코드가 있다. 우리가 원래 알던 useState을 이용해서 상태 변화를 나타낼 수 있다.

import React, { useState } from 'react';

function Counter() {
const [number, setNumber] = useState(0);

const onIncrease = () => {
setNumber(prevNumber => prevNumber + 1);
};

const onDecrease = () => {
setNumber(prevNumber => prevNumber - 1);
};

return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}

export default Counter;

useReducer 을 사용해서 나타내기

reducer 함수는 switch분기문을 이용하면 이해하기 쉽다.

import React, { useReducer } from 'react';

function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}

function Counter() {
const [number, dispatch] = useReducer(reducer, 0);

const onIncrease = () => {
dispatch({ type: 'INCREMENT' });
};

const onDecrease = () => {
dispatch({ type: 'DECREMENT' });
};

return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}

export default Counter;

위에서 보듯 action의 객체의 형태는 자유이다.

const [state,dispatch] = useReducer(reducer,initalState)

여기서 state는 우리가 컴포넌트에서 사용 할 수 있는 상태를 가리키고 dispatch는 액션을 발생시키는 함수이다. 이 함수는 dispatch({type : 'INCREMENT'})처럼 사용하면 된다. useReducer에 넣는 첫번째 파라미터는 reducer 함수이고 두번쨰 파라미터는 초기 상태이다.

0개의 댓글