1차 공부/React공부

useState+onClick, onChange, 그리고 불변성

공대탈출 2022. 11. 26. 10:53

useState + onClick

import React, { useState } from "react";

function App() {
  const [name, setName] = useState("길동이");

  function onClickHandler() {
    setName("누렁이");
  }

  return (
    <div>
      {name}
      <button onClick={onClickHandler}>버튼</button>
    </div>
  );
}

export default App;

State값을 '길동이'로 초기값을 만듭니다.

 

버튼에서 onClick에 반응할 함수를 만듭니다.

함수안에서 setName을 이용하여 onClick됐을 시 State값을 변경하도록 만들어 줍니다.

 

반환값에서 { name }으로 현재 적용되어있는 name값을 출력해줍니다.

button에 onClick함수를 적용하여 버튼 클릭 시 onClickHandler 함수가 작동하도록 합니다.

 

처음 State값인 '길동이'가 출력되어 있다가, 버튼을 클릭할 시 '누렁이'로 State가 바뀌고, 누렁이가 출력됩니다!

 

 

 

 

 

useState + onChange

// src/App.js

import React, { useState } from 'react';

const App = () => {
  const [value, setValue] = useState('');
  const onChangeHandler = (event) => {
    const inputValue = event.target.value;
    setValue(inputValue);
  };
  console.log(value);
  return (
    <div>
      <input type="text" onChange={onChangeHandler} value={value} />
    </div>
  );
};

export default App;

input을 type = text로 하나 만들어 줍니다.

State를 빈 문자열로 초기 설정해줍니다.

 

input과 생성한 State를 연결해줍니다.

이때 onChange를 사용해 inputValue를 event에서 target.value로 인풋 밸류값을 잡아주고,

setInput을 사용해 inputValue로 value값을 변경합니다.

 

그리고 확인하기위해 콘솔창에 value를 찍어보면 아래와 같습니다.

다시 설명하면 사용자가 input에 어떤 값을 입력하면 그 값을 입력할때마다, 같은말로 onChange될 때 마다,

value라는 State에 setValue해서 넣어주는 것입니다.

이러한 과정을 통해 우리는 사용자의 input값을 State로 관리할 수 있습니다.

위에서 사용한 onChangeHandler안의 event객체는 리액트개념이 아닌 HTML DOM event 개념입니다.

더 많은 내용은 공식문서 HTML이벤트나 아래 링크를 참조합시다.

 

[JS] 자바스크립트 이벤트 (onchange,onclick,onmouseover,onmouseout,onload,onkeydown)

HTML이벤트란 HTML요소에 발생하는 특정 사건을 의미합니다. HTML문서에 자바스크립트가 쓰였...

blog.naver.com

 

 

 

 

불변성

불변성이란 메모리에 있는 값을 변경할 수 없는 것을 말합니다.

자바스크립트의 데이터 형태중에 원시데이터는 불변성이있고, 아닌 데이터인 객체, 배열, 함수 등은 불변성이 없습니다.

 

 

만약 우리가 let number = 1이라고 선언을 하면 메모리에는 1이라는 값이 저장됩니다.

그리고 number라는 변수는 메모리에있는 1을 참조하죠.

그리고 이어서 let secondnumber = 1이라고 다른 변수를 선언했다고 가정해봅시다.

이때도 자바스크립트는 메모리에있는 1이라는 값을 참조합니다.

즉, number와 secondnumber의 변수의 이름은 다르지만, 값을 참조하는 메모리의 위치는 같은 것 입니다.

그래서 우리가 console,log(number === secondnumber)을 하면 true가 출력이 되는 것 입니다.

 

하지만 원시데이터가 아닌 값은 이러지 않습니다.

let obj1 = {name : 'kim'}이라는 값을 선언하면 메모리에 obj1이 저장이됩니다.

이어서 let obj2 = {name:'kim'}이라고 같은 값을 선언하면 obj2라는 새로운 메모리 공간에 새롭게 저장됩니다,

그래서 obj1 === obj2 는  false가 되는 것 입니다.

 

 

다시 원시데이터로 돌아와서 만약에 기존에 1이던 number을 number =2 라고 새로운 값을 할당하면 어떻게 될까요?

원시데이터는 불변성이 있습니다. 즉, 기존 메모리에 저장이 되어있는 1이라는 값이 변하지 않고,

새로운 메모리 저장공간에 2가 생기고 number라는 값을 새로운 메모리 공간에 저장된 2를 참조하게 됩니다.

그래서 콘솔에 secondNumber을 찍으면 여전히 1이라고 찍히는 것 입니다.

number과 secondNumber은 각각 다른 메모리 공간을 참조하고 있기 때문입니다.

 

이번엔 obj1.name = 'park'라고 새로운 값을 할당하면 어떻게 될까요?

객체는 불변성이 없습니다. 그래서 기존에 참조하던 {name :'kim'}이라는 값이 {name :'park'}으로 바뀝니다.

 

원시데이터는 수정을 했을 때 메모리에 저장된 값 자체는 바꿀 수 없고, 새로운 메모리 저장공간에 새로운 값을 저장합니다.

원시데이터가 아닌 데이터는 수정했을 때 기존에 저장되어있던 메모리 저장공간의 값 자체를 바꿔버립니다.

그래서 원시데이터는 불변성이 있지만, 원시데이터가 아닌 것들은 불변성이 없다고 하는 것 입니다.

 

 

 

리액트에서는 왜 원시데이터가 아닌 데이터의 불변성을 지켜주는 것을 중요시할까?

리액트에서는 화면을 리렌더링 할지 말지 결정할 때 state의 변화를 확인합니다.

state가 변했으면 리렌더링 하는 것이고, state가 변하지 않았으면 리렌더링을 하지 않습니다.

 

그때, state가 변했는지 변하지 않았는지 확인하는 방법이 state의 변화 전, 후의 메모리 주소를 비교합니다.

그래서 만약 리액트에서 원시데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지않고, 직접 수정을 가하면 값은 바뀌지만 메모리주소는 변함이 없게 되는 것 입니다.

따라서 개발자가 값은 바꿨지만, 리액트는 state가 변했다고 인지하지 못하여 일어나야할 리렌더링이 일어나지 않습니다.

 

 

 

 

리액트에서 불변성 지키기 예시

배열을 setState할 때 불변성을 지켜주기 위해 직접 수정을 하지 않고 전개 연산자를 사용해서 기존의 값을 복사한 후 값을 수정하는 식으로 구현합니다.

import React, { useState } from 'react';

function App() {
  const [dogs, setDogs] = useState(['말티즈']);

  function onClickHandler() {
    // spread operator(전개 연산자)를 이용해서 dogs를 복사합니다.
    // 그리고 나서 항목을 추가합니다.
    setDogs([...dogs, '시고르자브르종']);
  }

  console.log(dogs);
  return (
    <div>
      <button onClick={onClickHandler}>버튼</button>
    </div>
  );
}

export default App;

위와같이 ...dogs 전개연산자를 사용하여 값을 복사해오고 그 값을 수정하는 식으로 구현합니다.

 

 

 

원시데이터란?

원시데이터란 숫자, 문자열, 불리언값, null, undefined 등을 의미합니다.

객체가 아니면서 메서드도 가지지 않는 데이터 입니다.