useReducer()
useReducer(reducer, initState)
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 사용을 염두해 두도록!
useReducer
와 useContext
함께 사용하기export Context = React.createContext()
로 context 생성<Context.Provider value={{state1:state, dispatch2:dispatch}}>
컴포넌트 씌우기const xxxContext = useContext(Context)
: 사용할 컨텍스트 변수에 담기const [state1, dispatch2] = xxxContext
: distructure로 나눠 사용하기useReducer
Data FetchuseReduer
+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>
)
}
}