[useState] 자주 변경되는 값을 관리해보자!

·2022년 2월 3일

React Hooks

목록 보기
2/6
post-thumbnail

State?

component의 상태

  • useState를 생성 시, useState(초기값)을 넣어주면 → [state, setState]라는 배열로 return
  • state == 현재 상태값을 담은 변수
  • setState == state를 변경시켜주고 싶을 때 사용하는 함수
import React from 'react';

const[state, setState] = useState(초기값);

// import 안했다면 const[state, setState] = React.useState(초기값);
const[count, setCount] = React.useState(1);
//State: count = 1
setCount(6);
//State: count = 6;

useState(초기값)을 사용하면 
초기값 1이 담긴 변수 count,
변수 count를 수정할 수 있는 함수 setCount가 배열 형태로 반환된다

원래 모든 React Component는 새로고침을 누를 때마다 무죅건 reload됨.
이 불필요한짓이 맘에 안든다!
요 useState를 이용하면, setState를 사용해서 값이 변경될 때만 업데이트(렌더링), reload하게 됨!
그냥 새로고침 하면, 기본 component들만 reload 되고, useState를 사용한 부분은 그대로다.

import React, { Component, useState } from 'react';

function App() {
  const [time, setTime] = useState(1);
	
	const handleClick = () => {
		setTime(time + 1);
	}
  return (
    <div>
      <span>현재 시각: {time}</span>
      <button onClic={handleClick}>Update</button>
    </div>
  )
}
export default App;

setTime 함수를 이용해서 time을 update 시켜줄 때마다, component는 브라우저 상에서 다시 렌더링 되고, 업데이트된 state가 time에 들어감!

예시로 Upload 버튼을 누르면 이름을 출력하는걸 만들어보자

function App() {
  const [names, setNames] = useState(["홍길동", "김민수"]);

  return (
  <div>
    <input type="text"/>
    <button>Upload</button>
    {names.map((name, idx) => {
      return <p key={idx}>{name}</p>
    })}
  </div>
  );
}
export default App;

names 배열([”홍길동”, “김민수”])을 돌면서 item 하나하나마다 p tag를 걸어줌

이렇게 react에서 map을 써서 element(

{name}

)를 출력하게 되면, key가 꼭 있어야해서 추가(안해도 warning에서 멈추긴 함..)

과정

  1. input 태그에 적힌 값 받아오기
  2. Upload 버튼 클릭을 감지
  3. submit을 하면 기본 배열에 새로운 값을 추가하기
  4. 화면에 출력하기
💡 1. input 태그에 뭐가 적혀있는지 보기.
import React, { Component, useState } from 'react';

function App() {
  const [names, setNames] = useState(["홍길동", "김민수"]);
  const [input, setInput] = useState('');

  const handleInputChange = (e) => {
    setInput(e.target.value);
  };

  return (
  <div>
    <input type="text" value={input} onChange={handleInputChange}/>
    <button>Upload</button>
    {names.map((name, idx) => {
      return <p key={idx}>{name}</p>
    })}
  </div>
  );
}
export default App;

onChange를 넣어 변화를 감지하고, 변경사항이 있을 때마다 함수 handleInputChange를 호출
→ 변수 input의 값을 setInput 함수를 통해 변경

💡 2. 클릭을 감지하고, 초기값에 새로운 값 추가하기
import React, { Component, useState } from 'react';

import './App.css';

function App() {
  const [names, setNames] = useState(["홍길동", "김민수"]);
  const [input, setInput] = useState('');

  const handleInputChange = (e) => {
    setInput(e.target.value);
  };

  const handleUpload = (e) => {
    setNames((prevState) => {
      return([input, ...prevState]);
    });
  }

  return (
  <div>
    <input type="text" value={input} onChange={handleInputChange}/>
    <button onClick={handleUpload}>Upload</button>
    {names.map((name, idx) => {
      return <p key={idx}>{name}</p>
    })}
  </div>
  );
}
export default App;

input에 값을 넣고 Upload 버튼을 누르면, 기존 값에 input에 넣은 값을 추가하려 한다.
button에 onClick으로 이벤트를 감지하고, 클릭이 일어나면 handleUpload를 호출한다.
호출된 handleUpload는 names의 값을 setNames 함수를 통해 변경하는데, 이 때 콜백함수를 사용하게 된다.

그.. 그게뭐노
state를 변경할 때 새로운 state값이 이전의 state 값과 연관이 되어있다면,
callback 함수(setState의 인자로 새로운 state를 return하는 함수)를 사용하는걸 추천

const handleUpload = (e) => {
    setNames((prevState) => {
      return([input, ...prevState]);
    });
  }

callback 함수?
다른 함수의 인자로 전달된 함수

callback 함수의 인자는 우리가 update 하기 이전의 State 값임.(prevState)
return 안의 값이 새롭게 update가 될 state임.
return([]) 우리는 배열 속에 값을 넣고, 그걸 출력하는 방식이므로 
배열에 새로 들어온 값이 먼저 출력되도록 input을 먼저 넣고
뒤에 올값은 prevState(원래 있던 배열, 홍길동 김민수)인데 ...prevState로 넣어준다.

요렇게도 넣어보고 저렇게도 넣어본 결과

1. 
const handleUpload = (e) => {
    setNames((prevState) => {
      return([input, ...prevState]);
    });
  }
새로운값
홍길동
김민수
-- 새로운 값인 input이 앞에 넣은대로 잘 들어가고, ...prevState는 기본값으로 넣어둔것

2.
const handleUpload = (e) => {
    setNames((prevState) => {
      return([...prevState, input]);
    });
  }
-- 1에서 input을 뒤에 넣었으니 새로운 값이 마지막에 잘 나온다

3. const handleUpload = (e) => {
    setNames((prevState) => {
      return([input]);
    });
  }
홍길동
김민수
-- Upload 버튼 클릭 후
새로운값

기존의 새로운 값이 먼저 나와있다가, 버튼을 누르면 handleUpload가 호출되어 새로운 값만 남는다

[”홍길동”, “김민수”] + 개구리 → 개구리 홍길동 김민수

[”개구리”, ”홍길동”, “김민수”] + 강아지 → 강아지 개구리 홍길동 김민수

이런식으로 prevState는 계속 업데이트됨

어.. 그럼 이거도 초기값이 개무거운거라면 계속 불러오는건데 비효율적인거 아닌가?
→ 초기값을 값 그대로가 아닌 callback형태로 넣어주면 된다!

function veryHeavy() {
	console.log('와 무지하게 무겁다');
  	return (['홍길동', '김민수']);
}


const[name, setName] = useState(() => {
	return veryHeavy();
});

이러면 딱 맨 화면 reload에 한번만 부르고 끝!

별코딩님의 React Hooks 시리즈를 보고 정리하기 위해 작성했습니다!!

profile
어?머지?

0개의 댓글