Blog>
Snippets

Selecting State with React Hooks

Demonstrate selecting portions of the state within a component using the `useStoreState` hook for optimized rendering, focusing on filtering todos based on completion status.
import { createContext, useContext, useReducer } from 'react';
Import necessary hooks from React for creating context, utilizing context, and managing state with the useReducer hook.
const TodoContext = createContext();
Create a context for todo items.
const todoReducer = (state, action) => {
  switch (action.type) {
    case 'TOGGLE_TODO':
      return state.map(todo =>
        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo
      );
    default:
      return state;
  }
};
Define a reducer function to handle state changes based on actions, such as toggling the completion status of a todo item.
const TodoProvider = ({ children }) => {
  const initialState = [{ id: 1, task: 'Learn React Hooks', completed: false }];
  const [state, dispatch] = useReducer(todoReducer, initialState);

  return (
    <TodoContext.Provider value={{ state, dispatch }}>
      {children}
    </TodoContext.Provider>
  );
};
Create a TodoProvider component that provides the todos state and dispatch function to its children components.
const useStoreState = () => {
  const { state } = useContext(TodoContext);
  return state;
};
Define a custom hook to access the todo state from the context.
const useFilteredTodos = (completed = false) => {
  const todos = useStoreState();
  return todos.filter(todo => todo.completed === completed);
};
Define a custom hook for selecting todos based on their completion status, utilizing the useStoreState hook.
const TodoList = () => {
  const filteredTodos = useFilteredTodos(true);
  return (
    <ul>
      {filteredTodos.map(todo => (
        <li key={todo.id}>{todo.task}</li>
      ))}
    </ul>
  );
};
Use the useFilteredTodos hook in a component to render a list of completed todos.