Developer_hong

3. React useReducer, useState 본문

카테고리 없음

3. React useReducer, useState

Developer_hong 2022. 11. 3. 21:28
반응형

useState, useReducer 모두 state를 만들고 랜더링한다

useState를 통해서는 단순한 관리, useReducer을 통해서는 체계적인 관리를 할 수 있다

useState로 가능한 부분을 useReducer 사용할 경우 더 복잡해질 수 있기 때문에 적절한 사용이 필요하다

 

useState 사용을 위해서는  import React, { useState } from "react";

Generics를 통해 해당 상태가 타입형을 가질지 설정

const [state, setState] = useState<number>(1);

 

useReducer 사용을 위해서는 import React, { useReducer } from "react";

const [state, dispatch] = useReducer(reducer, initialState);

 

useState

useState('test'); // array가 만들어짐 ( array[0] = 'test', array[1] = array[0]을 수정할 수 있는 함수 )

-> 첫번째에는 state 데이터, 두번째에는 state 데이터 변경 함수

 

ES6의 destructuring 문법을 사용하여 담을 수 있음, array, object를 변수에 쉽게 담고 싶을 때 사용

ex) var [a, b] = [10, 100];


let [first, second] = useState('test'); //문자, 숫자 저장가능

let [first, second] = useState( [ 'test 1', ' test2' ] ); //array, object 등 저장가능

// first[0] = test 1

// first[1] = test 2

-> state를 사용하는 이유 : state에 담긴 값이 바뀌면, 그 데이터를 담고 있던 HTML이 재랜더링 된다 (웹이 App처럼 동작하도록 가능)

let으로 선언한 변수는 변경됐을 때 재랜더링 되지 않고 새로고침 필요

state는 그냥 변경이 되지않고 useState 선언시 생성한 함수로만 변경 가능

 

ex)

// useState 데이터는 직접 수정 불가능

let [myValue, valueChange] = useState( [ 'test1', 'test2', 'test3' ] );

myValue[0] = 'test'; // useState 변수는 직접 수정 불가능

valueChange(myValue); //변경 적용되지 않음

 

-> cf) 리액트에서 array/object 담은 변수는 직접 변수에 값을 가지고 있지 않고 RAM에 저장된 위치만 담고있음

let arr = [1,2,3]  --> arr는 [1,2,3]을 담고 있는 것이 아니라 [1,2,3]이 저장된 RAM 위치를 가르킴

따라서 myValue[0] = 'test'로 바꿨더라도 값은 바뀌었을지 모르지만 myValue가 가르키는 위치는 변경되지 않기 때문에 적용되지 않음

* useState는 state 값이 변경되지 않으면 바꿔주지 않는다 (자원낭비를 방지하기 위해서 재랜더링을 할 필요 없기 때문이다)

 

// useState 데이터는 전체 수정만 가능하므로 부분 수정Tip

let [test, testChange] = useState( [ 'test1', 'test2', 'test3' ] );

var newArray = [...test]; //...이라는 spread operator (중괄호, 대괄호 삭제) 사용하여 deep copy

(그냥 var newArray = test; 하면 값 공유가 된다 reference data type, react의 immutable data 특징입니다)

newArray[0] = 'test';

testChange( newArray );

 

useReducer

import { Action } from "@remix-run/router";
import React, { useReducer, useState } from "react";
import "./App.css";

function App() {
  type reduceAction = { cnt: number, type: 'INCREASE' } | { cnt: number, type: 'DECREASE' } | { cnt: number, type: 'RESET' }; // action을 | 사용하여 지정
  function countReducer(cnt:number,  action: reduceAction): number {
    switch (action.type) {
      case 'INCREASE':
        return cnt + 1;
      case 'DECREASE':
        return cnt - 1;
      case 'RESET' :
        return 0;
      default:
        throw new Error('Unhandled Action');
    }
  }

  const [count, countDispatch] = useReducer(countReducer, 0);

  return (
    <div className="App">
      <input type="button" value="-" onClick={ () => countDispatch({ type: 'DECREASE', cnt: count }) } />
      <input type="button" value={count} onClick={ () => countDispatch({ type: 'RESET', cnt: count }) } />
      <input type="button" value="-" onClick={ () => countDispatch({ type: 'INCREASE', cnt: count }) } />
    </div>
  );
}

export default App;

 

 

반응형