반응 후크: useContext

상태 관리



React 애플리케이션을 개발하는 동안 렌더링할 다른 페이지, 구성 요소가 있을 가능성이 큽니다. 이 경우 대부분의 구성 요소 자체에는 구성 요소 상태를 생성하는 데 사용할 수 있는 후크(기능 구성 요소)가 있습니다. 또한 내부 상태를 하위 구성 요소에 대한 소품으로 전달합니다.

// components/TodoList.js

const TodoList = () => {
  const [todoList, setTodoList] = useState([]);
    const [user, setUser] = useState({})

  return (
    <>
            <Header user={user}/>
            <Body user={user}/>
            <Footer user={user}/>
      {
        todoList.map(todo => <Todo todo={todo} key={todo.id} user={user}/>)
      }         
    </>
  );
}


컨텍스트 API



React Context는 React의 핵심 패키지에 있는 상태 관리 API입니다. 상태 관리 라이브러리에서 필요한 거의 모든 것에 Context API를 사용할 수 있습니다. 이를 사용하는 주요 목적은 props를 통해 전달하지 않고 여러 구성 요소 간에 데이터를 공유하는 것입니다.

모든 컨텍스트 소비자는 공급자에게 전달된 값이 변경될 때마다 다시 렌더링됩니다. 이 문제를 해결하는 한 가지 방법은 값 개체를 메모화하는 useMemo 후크를 사용하는 것입니다. 종속성 값이 변경될 때만 다시 생성됩니다.

이 기사에서는 Context API를 사용하여 todoList를 관리하려고 합니다.

TodoListContext 생성




// contexts/todoListContext.js

const TodoListContext = createContext([]);

const TodoListContextProvider = (props) => {
  const [todoList, setTodoList] = useState([]);

  // Only rerender when todoList changes
  const value = useMemo(() => [todoList, setTodoList], [todoList]);
  return (
    <TodoListContext.Provider value={value}>
      {props.children}
    </TodoListContext.Provider>
  )
}


사용자 정의 후크를 만들고 후크 내부의 일부 논리를 관리할 수도 있습니다.

// contexts/todoListContext.js

const useTodoList = () => {
  const context = useContext(TodoListContext);
  if (!context) {
    throw new Error("useTodoList must be used inside TodoListProvider")
  }

  return context;
}


그런 다음 구성 요소에서 이 후크를 사용할 수 있습니다.

// components/TodoList.js

const TodoList = () => {
  const [todoList, setTodoList] = useTodoList();

    const addTodo = (todo) => setTodoList([...todoList, todo]);

  return (
    <>
      {
        todoList.map(todo => <Todo todo={todo} key={todo.id} />)
      }
            <button onClick={() => { addTodo({ id: Math.random(), name: "New Todo" })}}>Add Todo</button>
    </>
  );
}


그런 다음 후크를 개선하기 위해 우리가 할 수 있는 것은 컴포넌트에서 외부 로직을 제거하고 후크 자체에 추가할 수 있다는 것입니다. 따라서 여기에서 addTodo 함수를 제거하고 useTodoList 훅으로 이동할 수 있습니다. 그리고 이 상황에서 useState 대신 useReducer를 사용할 수도 있습니다.

useReducer는 작업의 복잡성을 줄이고 사용성을 높일 수 있습니다.

// contexts/todoListContext.js

const todoReducer = (state, action) => {
  switch (action.type) {
    case "NEW": return [...state, action.payload]
    case "DELETE": return state.filter(todo => todo.id != action.payload);
    default: return state;
  }
}

const useTodoList = () => {
  const context = useContext(TodoListContext);
  if (!context) {
    throw new Error("useTodoList must be used inside TodoListProvider")
  }

    const [todoList, setTodoList] = context;

    // Hook Functions
  const addTodo = (todo) => dispatch({ type: "NEW", payload: todo })
  const removeTodo = (todoId) => dispatch({ type: "DELETE", payload: todoId });

  return {
        todoList,
        setTodoList,
        addTodo,
        removeTodo
    };
}


최종 코드는 다음과 같습니다.

const TodoListContext = createContext([]);

const todoReducer = (state, action) => {
  switch (action.type) {
    case "NEW": return [...state, action.payload]
    case "DELETE": return state.filter(todo => todo.id != action.payload);
    default: return state;
  }
}

const TodoListContextProvider = (props) => {
  const [state, dispatch] = useReducer(todoReducer, []);

  const value = useMemo(() => [state, dispatch], [state]);
  return (
    <TodoListContext.Provider value={value}>
      {props.children}
    </TodoListContext.Provider>
  )
}

const useTodoList = () => {
  const context = useContext(TodoListContext);
  if (!context) {
    throw new Error("useTodoList must be used inside TodoListProvider")
  }

  const [state, dispatch] = context;

  // Hook Functions
  const addTodo = (todo) => dispatch({ type: "NEW", payload: todo })
  const removeTodo = (todoId) => dispatch({ type: "DELETE", payload: todoId });

  return {
    todos: state,
    dispatch,
    addTodo,
    removeTodo
  };
}

export { TodoListContextProvider, useTodoList


참조



Application State Management with React

How to use React Context effectively

Hooks API Reference - React

좋은 웹페이지 즐겨찾기