관심쟁이 영호

[React #4] JSX 문법 ㅣ UserState 본문

Front-End/React

[React #4] JSX 문법 ㅣ UserState

관심쟁이 영호 2021. 5. 8. 01:05
반응형

이번에는 UserState에 대해서 공부를 해보자!

 

먼저 아래의 코드를 보자.

 let number = 1;
const add = () =>{
  number++;
  console.log('add', number);
}
  
  return (
  <div>
    <div>
      <h1>숫자 : {number}</h1>
      <button onClick={add}>더하기</button>
    </div>
</div>
  );

local:3000 으로 접속해서

"더하기" 버튼을 클릭하면 console로 number 값을 확인할 수 있다.

 

하지만 숫자: {number}인데

number 값을 +1을 해주어도

"숫자 : 1" 에서 1이 바뀌지 않는다 왜그럴까?

 

  • 상태 값이 변경되었다는 신호를 보내야 한다.

리액트는 아무 변수나 상태 값으로 생각하지않는다.

그래서 "이 변수를 상태 값으로 설정할게!" 라고 해주어야 한다.

그리고 값이 변하면 "상태 값이 변경되었어!" 라고 말해주어야 한다.

 

어떻게 하는 걸까?

아래의 코드를 통해서 수정된 모습을 보자.

 

//let number = 1;
  const [number, setNumber] = useState(1);

const add = () =>{
  setNumber(number + 1);
  console.log('add', number);
}
  
  return (
  <div>
    <div>
      <h1>숫자 : {number}</h1>
      <button onClick={add}>더하기</button>
    </div>
</div>
  );

이렇게 하면 성공적으로 UI 변경이 일어나는 모습을 볼 수 있다.

 

바뀐 것을 살펴보자.

  • let number = 1; --------> const [number, setNumber] = useState(1);

useState()를 통해서 해당하는 number를 상태 값으로 설정한다는 뜻이다.

setNumber 부분은 해당하는 number의 값이 변경되었다는 것을 알려주는 메소드의 이름을 설정하는 것이다.

 

setNumber(number + 1); 의 부분을 보면 알 수 있듯이,

상태값 number의 값이 바뀌었다는 것을 알 수 있다.

 

그래서 자동으로 변경 감지를 해서 UI가 변경되었다.

 

이것은 React안에 hooks 라이브러리 상태값이 되는 것이다.

 


응용해보자!

const[users, setUsers] = useState([]);

  const download = () =>{
    let sample = [
      {id:1, name:"유재석"},
      {id:2, name:"강호동"},
      {id:3, name:"이수근"},
      {id:4, name:"신동엽"},
    ]

    setUsers(sample);
  }

  
  return (
  <div>
    <button onClick={download}>다운로드</button>
    {users.map((u) => (
      <h1>
        {u.id}, {u.name}
      </h1>
    ))}
</div>
  );

위의 코드를 보면

users 배열은 처음에는 아무 값도 없다가

"다운로드" 버튼을 클릭하면 download 함수가 실행되고,

users에 object들이 들어가고 상태 값이 변경(정확히는 레퍼런스가 변경)되어 ui가 변경되는 것을 볼 수 있다.

그럼 아래와 같이 처음부터

똑같은 Object들이 들어있다면

다운로드를 클릭했을 때, 똑같이 렌더링이 된 것일까?

(다시 페이지를 불러온 것일까?)

그것을 확인하기 위해서 Console을 찍어보았다.

function App() {
  console.log("App 실행됨");
  const[users, setUsers] = useState([
    {id:1, name:"유재석"},
    {id:2, name:"강호동"},
    {id:3, name:"이수근"},
    {id:4, name:"신동엽"},
  ]);

  const download = () =>{
    let sample = [
      {id:1, name:"유재석"},
      {id:2, name:"강호동"},
      {id:3, name:"이수근"},
      {id:4, name:"신동엽"},
    ]

    setUsers([...sample]);
  }

  
  return (
  <div>
    <button onClick={download}>다운로드</button>
    {users.map((u) => (
      <h1>
        {u.id}, {u.name}
      </h1>
    ))}
</div>
  );

 

페이지를 처음 열면, users에 정보가 있기 때문에

Object들이 화면에 그려져 있다.

 

"다운로드" 버튼을 클릭해보자.

맨 처음에 그릴 때,

console인 "App 실행됨"이 실행된 것을 볼 수 있다.

 

근데 "다운로드"를 클릭했을 때,

새로 App 실행됨이 실행된 것을 볼 수 있다.

왜일까?

상태값은 똑같은 값인데, 왜 렌더링이 새롭게 되는것일까?

 

이유는 "sample"에 있다.

sample에서 새로운 레퍼런스를 받게 되고, 그것이 할당되기 때문에

상태 값이 변경된 것이다.

 

결과적으로, "다운로드"를 클릭할 때마다 상태 값은 변한게 없지만

ui를 새로 그린 것을 알 수 있다.

 

해결 : download에서 sample을 빼낸다. 그럼 download 함수가 실행될 때마다, 새롭게 sample을 할당하지 않을테니까.

 


이번에는 그럼 이 코드를 보자.

let sample = [
  {id:1, name:"유재석"},
  {id:2, name:"강호동"},
  {id:3, name:"이수근"},
  {id:4, name:"신동엽"},
]
function App() {
  console.log("App 실행됨");
  const[users, setUsers] = useState(sample);
  

  const download = () =>{
    
    sample.push({id: 5, name :'김흥국'});
    console.log(sample);
    setUsers(sample);
  }

  
  return (
  <div>
    <button onClick={download}>다운로드</button>
    {users.map((u) => (
      <h1>
        {u.id}, {u.name}
      </h1>
    ))}
</div>
  );

"다운로드" 버튼을 클릭할 때마다,

{id: 5, name: '김흥국'}이라는 Object를 push 했다.

 

그럼 다운로드를 누를 때 마다, Object가 추가되고

UI에 추가되어야 한다고 예상할 수도 있다.

 

하지만, 변경되지 않는다.

실제로 sample 배열에 Object는 추가된다.

하지만 UI는 변경이 없다.

 

이유는 레퍼런스의 변경이 없기 때문이다.

그럼 어떻게 해결해야할까?

 

  • concat을 사용하자!
const download = () =>{
    
    const b = sample.concat({id: 5, name :'김흥국'});
    
    setUsers(b);
  }

 

위 코드처럼 바꾸면 성공적으로 ui가 변경되는 것을 볼 수 있다.

300x250
Comments