React Hooks #5 useReducer()

eunji hwang·2020년 7월 12일
0

REACT

목록 보기
6/16
post-custom-banner

useReducer()

참고 : codevolution-react-hooks-useReducer 유튜브영상

  • useReducer는 리엑트 훅스의 상태관리자
  • useReducer(reducer, initState)
  • state와 dispatch를 리턴 : state는 관리할 상태값, dispatch는 state를 변경할 함수
  • dispatch(액션타입) : dispatch에게는 액션타입을 인자로 전달한다.
  • 리덕스 사용법과 비슷허이~!
import React, { useReducer } from 'react'

const initState = 0 // 객체가능! { name: '이름', age: 22, count:0}
const reducer = (state, action) => {
  const [ type, value ] = action;
  switch(type) {
    case '증가':
      return state + 1
    case '감소':
      // initState = { name: '이름', age: 22, count:0} 일때
      return { 
        ...state, 
        count : state - value}
    case '리셋':
      return initState
    default :
      return state
  }
}
const CounterCompo=()=>{
  const [count, dispatch] = useReducer(reducer, initState);
  return (
    <div>
      {count}
      // 방법 1 : dispatch('액션타입명')
      <button onClick={()=>{dispatch('증가')}}>증가</button>
      
      // 방법 2 : dispatch({ type: 액션타입명, value: 5 })
      <button onClick={()=>{dispatch({ type: '감소', value: 5 })}}>감소</button>
      
      <button onClick={()=>{dispatch('리셋')}}>리셋</button>
    </div>
  )
}

활용

usestate(객체) 대신 사용

객체로 state를 관리하는 경우를 위해 useReducer훅을 제공한다. 이와 같이 사용할 경우 useReducer 사용을 염두해 두도록!

useReduceruseContext 함께 사용하기

codevolution-useContext+useReducer

  • 최상위 루트 컴포넌트
    • useReducer로 상태관리할 state, dispatch 생성
    • export Context = React.createContext() 로 context 생성
    • <Context.Provider value={{state1:state, dispatch2:dispatch}}> 컴포넌트 씌우기
  • consumer 컴포넌트
    • const xxxContext = useContext(Context) : 사용할 컨텍스트 변수에 담기
    • const [state1, dispatch2] = xxxContext : distructure로 나눠 사용하기

useReducer Data Fetch

codevolution-useReducer-data-fetch #2

useReduer+axios 사용하여 데이터 페치하기

  • npm i axios
import React, { useEffect, useReducer } from 'react'
import axios from 'axios'

const initState = {
  // useReducer로 관리할 state객체 초기값
  loading : true,
  errorMessage : '',
  post : {}
}

const reducer = ( state, action ) => {
  // 리듀서 함수 작성
  switch(action.type){
    case 'FETCH_SUCCESS' : // 성공일때
      return {
        loading : false,
        errorMessage : '',
        post : action.payload, // res.data payload로 전달
      }
    case 'FETCH_ERROR':
      return {
        loading : false,
        errorMessage : 'Something went wrong!'
        post : {}
      }
    default :
      return state
  }
const DataFetchCompo = () => {
  const [ state, dispatch ] = useReducer(reducer, initState);
  const {loading, errorMessage, post} = state
  
  useEffect(() => {
    axios.get('URL')
         .then(res => dispatch({type:'FETCH_SUCCESS', payload: res.data}))
         .catch(error => dispatch({type:'FETCH_ERROR'}))
  },[])
  return (
    <div>
      { loading ? 'loading..' : post.title }
      { errorMessage ? errorMessage : null }
    </div>
  )
}
}

profile
TIL 기록 블로그 :: 문제가 있는 글엔 댓글 부탁드려요!
post-custom-banner

0개의 댓글