React useReducer

Created By: chatGPT

The useReducer hook in React is a powerful tool for managing complex state logic in functional components. It's an alternative to useState when you need more control over state transitions. With useReducer, you can encapsulate your state management into a single reducer function that handles changes in the application state based on dispatched actions. This can lead to more readable and maintainable code, especially when dealing with multiple pieces of related state. Key aspects of useReducer include defining the initial state, creating a reducer function, and using the returned state and dispatch function to manage state updates.
import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count - 1 };
        default:
            throw new Error();
    }
}

function Counter() {
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <div>
            <p>Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'increment' })}>+</button>
            <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
        </div>
    );
}

export default Counter;
This simple example demonstrates a counter component that utilizes useReducer. The state consists of a single property, count. The reducer function specifies how to update the state based on action types such as 'increment' or 'decrement'. When a button is clicked, the corresponding action is dispatched, and the state is updated accordingly.
import React, { useReducer } from 'react';

const initialState = { todos: [] };

function todosReducer(state, action) {
    switch (action.type) {
        case 'add':
            return { todos: [...state.todos, action.payload] };
        case 'remove':
            return { todos: state.todos.filter((_, index) => index !== action.payload) };
        default:
            throw new Error();
    }
}

function TodoList() {
    const [state, dispatch] = useReducer(todosReducer, initialState);
    const [input, setInput] = React.useState('');

    const handleSubmit = (e) => {
        e.preventDefault();
        dispatch({ type: 'add', payload: input });
        setInput('');
    };

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input value={input} onChange={(e) => setInput(e.target.value)} />
                <button type='submit'>Add Todo</button>
            </form>
            <ul>
                {state.todos.map((todo, index) => (
                    <li key={index}>
                        {todo} <button onClick={() => dispatch({ type: 'remove', payload: index })}>Remove</button>
                    </li>
                ))}
            </ul>
        </div>
    );
}

export default TodoList;
Introduction And SetupComponentsPropsStateLifecycle MethodsHooksContext APIJsx SyntaxVirtual DomEvent HandlingFormsRoutingPerformance OptimizationError BoundariesHigher Order ComponentsRender PropsPortalsFragmentsRefsControlled ComponentsUncontrolled ComponentsMemoizationSuspenseLazy LoadingProp TypesDefault PropsConditional RenderingList And KeysAccessibility (a11y)State ManagementTestingCustom HooksUseEffectUseStateUseContextUseReducerUseMemoUseCallbackUseRefUseLayoutEffectUseImperativeHandleUseDebugValueAutomatic BatchingSuspense For Data FetchingStrict ModeForward RefsCreateContextLazyUseTransitionUseDeferredValueUseId