Skip to content

Instantly share code, notes, and snippets.

@shoveller
Last active January 21, 2022 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shoveller/59cbf7020f232a315358dc4d79dbecdc to your computer and use it in GitHub Desktop.
Save shoveller/59cbf7020f232a315358dc4d79dbecdc to your computer and use it in GitHub Desktop.
useState의 대안으로 useReducer 사용하기
import {useCountContext} from "./store/counter";
import './App.css'
const Viewer = () => {
const {count} = useCountContext()
return <p>
count is: {count}
</p>
}
function App() {
const {increment, decrement, reset} = useCountContext()
return (
<div className="App">
<p>
<button onClick={increment}>증가</button>
<button onClick={decrement}>감소</button>
<button onClick={reset}>리셋</button>
</p>
<Viewer/>
</div>
)
}
export default App
import { useReducer, Reducer, createContext, FC, useContext, useState} from "react";
const initializer = (count = 0) => {
return {count}
}
const reducer: Reducer<ReturnType<typeof initializer>, { type: 'increment' | 'decrement' | 'reset', payload?: number }> = (state, action) => {
return {
increment: {count: state.count + 1},
decrement: {count: state.count - 1},
reset: initializer(action.payload)
}[action.type]
}
/**
* state와 액션을 정의한 커스텀 훅
*/
const useCounter = () => {
const [state, dispatch] = useReducer(reducer, 0, initializer)
return {
count: state.count,
increment() {
dispatch({type: 'increment'});
},
decrement() {
dispatch({type: 'decrement'});
},
reset() {
dispatch({type: 'reset', payload: 0});
}
}
}
/**
* 커스텀 훅의 리턴을 저장할 컨텍스트
*/
const CountContext = createContext({
count: 0,
increment: () => {},
decrement: () => {},
reset: () => {},
})
export const useCountContext = () => useContext(CountContext)
/**
* 커스텀 훅의 반환값 자체를 하위 컴퍼넌트에 전파하는 프로바이더
* @param children
* @constructor
*/
export const CounterProvider: FC = ({children}) => {
const value = useCounter()
return <CountContext.Provider value={value}>{children}</CountContext.Provider>
}
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import {CounterProvider} from "./store/counter";
import App from './App'
ReactDOM.render(
<React.StrictMode>
<CounterProvider>
<App/>
</CounterProvider>
</React.StrictMode>,
document.getElementById('root')
)
@shoveller
Copy link
Author

shoveller commented Jan 21, 2022

useReducer는 React의 기본 제공 함수이며 useState의 대체품이 될 수 있다.
useState와 같은 동작을 하므로 호출할 때마다 새로운 state가 생긴다.
이것을 전용 컨텍스트에 할당해서 사용한다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment