DRAKE

RESUME

React Context API, useReducer로 전역 상태 관리 만들기

2023/03/13

4 min read

DEVELOPMENT

thumbnail

Context API

  • Context는 props드릴링을 줄이기 위해 사용합니다
  • Context를 사용하면 props로 넘겨주지 않아도 하위 트리의 모든 구성 요소에서 해당 값을 사용할 수 있어요

useReducer

  • useState와 비슷합니다 상태관리를 할 수 있어요
  • useState가 더 적은 코드를 작성하지만 많은 이벤트 핸들러를 통해 값을 수정하는 경우 코드를 줄이는데 useReducer가 적합할 수 있어요
  • useState는 상태 업데이트가 단순할 때 가독성이 좋지만 복잡해지면 어려울 수도 있어요 useReducer는 발생한 이벤트와 해당하는 로직을 명확하게 구분이 가능해요

Context 생성

우선 Context를 만들기 위해 CreateContext를 이용하여 만들어 줍니다

1

const TodoStateContext = createContext(null);

2

const TodoDispatchContext = createContext(null);

State값을 관리할 Context와 dispatch함수를 관리할 Context 해서 두개의 ConText를 생성해줍니다

reducer 정의

useReducer에서 사용할 reducer를 만들어주겠습니다

1

todo = {

2

id: number,

3

content: string,

4

isComplete: boolean,

5

};

1

function reducer((state,action)){

2

switch(action.type){

3

case 'ADD_TODO':

4

state.push(action.todo);

5

break;

6

case 'DELETE_TODO':

7

return state.filter(prev => prev.id !== action.todo.id)

8

default:

9

throw new Error('Unhandle Action')

10

}

11

}

간단하게 todo추가와 삭제만 설정해두었습니다

Context.Provider

이제 Context.Provider로 감싼 컴포넌트를 만들어볼께요

1

function TodoProdiver({ children }) {

2

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

3

4

return (

5

<TodoStateContext.Provider value={state}>

6

{' '}

7

//value: 공유할 값을 넣어준다

8

<TodoDispatchContext.Provider value={dispatch}>{children}</TodoDispatchContext.Provider>

9

</TodoStateContext.Provider>

10

);

11

}

12

13

export default TodoProvider;

14

15

export function useTodoState() {

16

const state = useContext(TodoStateContext);

17

if (!state) throw new Error('cannot find Provider');

18

return state;

19

}

20

21

export function useTodoDispatch() {

22

const dispatch = useContext(TodoDispatchContext);

23

if (!dispatch) throw new Error('cannot find Provider');

24

return dispatch;

25

}

먼저 TodoProvider를 보시면 useReducer를 사용하여 아까 만들어 두었던 reducer를 추가해주고,초기값은 []로 설정해주었습니다 return에는 만들어 두었던 Context.Provider로 children감싸서 반환해줍니다

useTodoState,useTodoDispatch를 통해 쉽게 state값과 dispatch함수를 가져올 수 있도록 만들어 두었습니다

사용하기

우선 Provier를 적용시켜줘야합니다 최상단 파일에서 만들어 두었던 TodoProvider를 감싸주시면 됩니다 예로 App.jsx에 감싸보겠습니다

1

import React from 'react';

2

import Router from '../../../src/router';

3

import TodoProvider from '../../../src/component';

4

5

function App() {

6

return (

7

<TodoProvider>

8

<Router />

9

</TodoProvider>

10

);

11

}

12

13

export default App;

1

function TodoPage(){

2

const todoState = useTodoState()

3

const dispatch = useTodoDispatch()

4

5

const handleAddTodo = (todo) =>{

6

dispatch({

7

type:'ADD_TODO',

8

todo:{

9

id,

10

content,

11

isComplete

12

}

13

})

14

}

15

16

const handleDeleteTodo = (id) => {

17

dispatch({

18

type:'DELETE_TODO',

19

todo:{

20

id,

21

content,

22

isComplete

23

}

24

})

25

}

26

return(

27

{todostate.map(todo => (

28

<div>

29

{todo.content}<button onClick={handleDeleteTodo}>삭제</button>

30

</div>))}

31

)

32

}

이벤트마다 함수를 정의하고 dispatch에 type과 필요한 data를 넘겨주어 useReducer를 통해 state값을 변경할 수 있습니다

profile

한동룡