본문 바로가기

React Native

React #6 - 리엑트훅(useReducer, useRef)

UseEffect - 사이드 이펙트를 사용할 때 쓰는 훅
매개변수 : setup 함수, [] 배열

생략 -> 항상 호출됨

빈배열 -> 최초 마운트 시에 호출된다. 

지정값이 들어간 배열 -> 해당 값이 변경된 경우에만 setup함수 호출

 

 

 


 

 

 

reduce 메서드

 

reducer

reducer가 한번 호출될때마다 다음번 매개변수에 마지막 리턴값을 전달한다. 

state가 다음번 useReducer 될 때 업데이트 되는 것이다! 

 

 

예제 1. 은행 (입금 /출금) 프로그램

import { useState } from "react";
import { useReducer } from "react";
import Button from "./Button";


const reducer = (state, action) => {
  switch(action.type){
    case 'DEPOSIT':
      return state + action.payload;
    case 'WITHDRAW' :
      return state - action.payload;
    default :
      return state;
  }
};


function Account() {
  const [money, setMoney] = useState('');
  const [account, dispatch] = useReducer(reducer, 0);
  //dispatch 함수를 호출하여, 해당 함수를 사용할 수 있는 것이다.
  //reducer은 작업을 진행할 함수이다.

  const depositDown = () =>{
    dispatch({type: 'DEPOSIT', payload: money});
  }

  const withdrawDown = () =>{
    dispatch({type: 'WITHDRAW', payload: money});
  }

  return(

    <>
        <p>잔고 : {account}</p>
        <input type="text" onChange={(e)=>setMoney(parseInt(e.target.value))} />
        <Button onClick = {depositDown} value = '예금' />
        <Button onClick = {withdrawDown} value = '출금' />
      </>
  );
}

export default Account;

 

useReducer 작성법!

1. const [account, dispatch] = useReducer(reducer, 0); 

 - account : 현재 state 상태를 나타낸다.  reducer 함수에 자동으로 전달됨  (reducer이 돌면서 업데이트 된다. )

 - dispatch : reducer을 작동시키는 함수? 라고 이해함

 - reducer 실제 행동을 취하는 함수! 그렇기 때문에 (state, action) 을 인자로 받는다. 

 

action에는 객체를 전달하는데, type을 주로 전달하여

switch문을 작성한다. 

 

switch(action.type){
    case ~~~ : 
}

 

 

 


 

 

useRef : 값을 관리는 하지만, 값이 변경되어도 리렌더링을 하지 않음! => 불필요한 호출 줄인다. 
값에 접근할 때 : current를 붙인다. 
매개변수 : 초기값

 

 

용법1. 불필요한 렌더링을 방지한다 : 렌더링이필요하여 useState로 변경했던 것들을 useRef로 변경해주면 렌더링이 일어나지 않고 값만 관리한다! 

  const num = useRef(1);

 

   <input type="number" style={{ width: '40px' }} defaultValue="1"  //ref를 쓸 때에는 defaultValue로 지정 필요
        onChange={e => num.current = Number(e.target.value) } />

defaultValue으로 초깃값을 주어야한다!!  

num,current에다가 타겟값을 넣어주고 값을 꺼내주는 것이다. (리렌더링x)

 

 

 

 

용법 2. dom 객체를 직접 접근할일이 있을 때 document의 queryselector를 쓰지 않고 useRef를 쓰면 된다. 

import { useRef, useState } from "react";
import PropTypes from 'prop-types';

function TodoInput({ addItem }){
  const [title, setTitle] = useState('');
  const titleElem = useRef();

  const handleAdd = () => {
    if(title.trim() !== ''){
      const item = { title };
     
      addItem(item);
      setTitle('');
      titleElem.current.focus();
    }
  };

  const handleKeyUp = event => {
    if(event.key === 'Enter') handleAdd();
  };

  return (
    <div className="todoinput">
      <input ref={ titleElem } type="text" value={ title } onChange={ event => setTitle(event.target.value) } onKeyUp={ handleKeyUp } autoFocus />
      <button type="button" onClick={ handleAdd }>추가</button>
    </div>
  );
}

TodoInput.propTypes = {
  addItem: PropTypes.func
};

export default TodoInput;

 

 

 

 

 

예제 1. 은행 프로그램에 input 요소를 useRef 로 변경하기 ! => 왜냐하면 렌더링이 필요 없는 값이기 때문에!!! 

사실상 input요소 안의 money 값은 버튼이 클릭되었을 때만 렌더링하면 된다. 그렇기 때문에~ 한번 useRef 로 작성해보자 

import { useState } from "react";
import { useReducer, useRef } from "react";
import Button from "./Button";



const reducer = (state, action) => {
  switch(action.type){
    case 'DEPOSIT':
      return state + action.payload;
    case 'WITHDRAW' :
      return state - action.payload;
    default :
      return state;
  }
};


function Account() {
  // const [money, setMoney] = useState('');
  // useRef 를 사용해서 작성해보자!
  const money = useRef(0);
  const [account, dispatch] = useReducer(reducer, 0);
  //dispatch 함수를 호출하여, 해당 함수를 사용할 수 있는 것이다.
  //reducer은 작업을 진행할 함수이다.

  const depositDown = () =>{
    dispatch({type: 'DEPOSIT', payload: money.current});
  }

  const withdrawDown = () =>{
    dispatch({type: 'WITHDRAW', payload: money.current});
  }

  return(

    <>
        <p>잔고 : {account}</p>
        <input type="text" defaultValue="0" onChange={(e) => {money.current = Number(e.target.value)
        console.log(money.current)}} />
        <Button onClick = {depositDown} value = '예금' />
        <Button onClick = {withdrawDown} value = '출금' />
      </>
  );
}

export default Account;

 

 

 

useRef 작성 방법

1. const money = useRef(0) 

 - money였던 input은 렌더링하지 않겠다는 뜻이다. 초기값은 0이다. 

 - 값에 접근하기 위해서는 무조건 .current로 접근한다!!! 

 - 따라서, onChange 함수에서  정의할 때에는 input 값의 value를 current 값으로 넣어주는 코드를 실행해야한다. 

(e) => {
money.current = e.target.value; 
}

 

 

 

 

< 만약 DOM 객체라면? - focus 예제>

1. const dom = useRef('') //초기화를 해주고, 

2. focus의 주체가되는 태그 속성에 ref 를 추가한다. 

<input ref = {dom} ... />

 

3. click 태그의 handle 함수에 focus를 정의한다. 

dom.current.focus();