- UseEffect Hook
- useEffect Syntax and Basic Usage
- Running Effects on Component Mount
- Handling Side Effects in React ()
- useEffect with Dependencies
- Cleanup Function in useEffect
- Fetching Data with useEffect
- useEffect vs useLayoutEffect
- Performance Optimization with useEffect
- Debugging useEffect Issues
- Best Practices for useEffect
- Conclusion
useEffect Hook in React
React’s useEffect hook enables side effects in functional components—such as data fetching, subscriptions, DOM updates, and timers—replacing lifecycle methods like componentDidMount and componentWillUnmount.
useEffect Syntax and Basic Usage
useEffect(() => {
// Code to execute (the side effect)
});
It accepts a callback function and an optional dependency array to control execution.
When to Use useReducer()
Running Effects on Component Mount
useEffect(() => {
console.log('Component mounted!');
}, []);
Use an empty array to run the effect only once after the initial render.
Basic Structure of useReducer()
To understand how usereducer in react works, let’s first take a look at its basic structure.
Reducer Function
A reducer function is where you define how the state should change based on an action. It typically takes two arguments: the current state and the action.
- function reducer(state, action) {
- switch (action.type) {
- case ‘increment’:
- return { count: state.count + 1 };
- case ‘decrement’:
- return { count: state.count – 1 };
- default:
- return state;
- }
- }
- state: The current state of the component.
- action: The action object dispatched to the reducer, usually containing a type property.

Using useReducer() Hook
const [state, dispatch] = useReducer(reducer, { count: 0 });
- state: Holds the current state ({ count: 0 } in this case).
- dispatch: Function used to dispatch actions (e.g., dispatch({ type: ‘increment’ })).
Implementing usereducer in React
Now, let’s look at how useReducer() can be used in practice with a few examples.
Simple Counter Example
In this example, we’ll create a simple counter application where users can increment or decrement the count.
- import React, { useReducer } from ‘react’;
- function counterReducer(state, action) {
- switch (action.type) {
- case ‘increment’:
- return { count: state.count + 1 };
- case ‘decrement’:
- return { count: state.count – 1 };
- default:
- return state;
- }
- }
- function Counter() {
- const [state, dispatch] = useReducer(counterReducer, { count: 0 });
- return (
- <div>
- <p>Count: {state.count}</p>
- <button onClick={() => dispatch({ type: ‘increment’ })}>Increment</button>
- <button onClick={() => dispatch({ type: ‘decrement’ })}>Decrement</button>
- </div>
- );
- }
- export default Counter;
In this example:
- We define a counterReducer function that handles the actions (increment and decrement).
- We use useReducer() to manage the state (count) and dispatch actions to update it.
- The dispatch() function is called with an action object that tells the reducer how to update the state.
Form Handling with useReducer()
useReducer() can also be very useful for managing form state, especially when the form has multiple fields that need to be updated independently.
- import React, { useReducer } from ‘react’;
- function formReducer(state, action) {
- switch (action.type) {
- case ‘update_field’:
- return { …state, [action.field]: action.value };
- case ‘reset’:
- return { name: ”, email: ” };
- default:
- return state;
- }
- }
- function Form() {
- const [state, dispatch] = useReducer(formReducer, { name: ”, email: ” });
- const handleChange = (e) => {
- const { name, value } = e.target;
- dispatch({ type: ‘update_field’, field: name, value });
- };
- const handleSubmit = (e) => {
- e.preventDefault();
- console.log(state);
- dispatch({ type: ‘reset’ });
- };
- return (
- <form onSubmit={handleSubmit}>
- <div>
- <label>Name:</label>
- <input
- type=”text”
- name=”name”
- value={state.name}
- onChange={handleChange}
- />
- </div>
- <div>
- <label>Email:</label>
- <input
- type=”email”
- name=”email”
- value={state.email}
- onChange={handleChange}
- />
- </div>
- <button type=”submit”>Submit</button>
- </form>
- );
- }
- export default Form;
In this example:
- We manage the form’s state using useReducer() and dispatch actions to update individual fields.
- The handleChange function dispatches the update_field action whenever an input field is changed.
- The handleSubmit function logs the state and resets the form using the reset action.
Complex State Management Example
For more complex state management, useReducer() becomes even more useful. Here’s an example that handles multiple properties in the state and multiple actions.
- const toggleTodo = (id) => {
- dispatch({ type: ‘toggle_todo’, payload: id });
- };
- return (
- <div>
- <button onClick={() => addTodo(‘Learn React’)}>Add Todo</button>
- <ul>
- {state.todos.map((todo) => (
- <li key={todo.id}>
- <span
- onClick={() => toggleTodo(todo.id)}
- style={{ textDecoration: todo.completed ? ‘line-through’ : ‘none’ }}
- >
- {todo.text}
- </span>
- <button onClick={() => removeTodo(todo.id)}>Remove</button>
- </li>
- ))}
- </ul>
- </div>
- );
- export default TodoApp;
In this example:
- We manage an array of todos and provide actions to add, remove, or toggle the completed status of a todo item.
- The todoReducer processes these actions, making the state updates predictable and easy to follow.
Looking to Master Business Intelligence? Discover the Business Intelligence Master Program Training Course Available at ACTE Now!
Advantages of Using useReducer()
- Better for Complex Logic: It’s easier to handle complex state changes and interactions with useReducer() compared to useState().
- Predictable State Updates: Since the state transitions are handled in one place (the reducer), it’s easier to follow and debug.
- Scalable: As your application grows, useReducer() scales better than useState() when dealing with multiple state variables or actions.

When Not to Use react native usereducer
While useReducer() is powerful, it’s not always necessary. For simpler state management, useState() may be more appropriate and easier to work with. Use useReducer() when you have:
- Multiple state transitions.
- Complex state logic.
- State that depends on other pieces of state.
Want to Learn About Business Analyst? Explore Our Business Analyst Interview Questions and Answers Featuring the Most Frequently Asked Questions in Job Interviews.
Best Practices for react native usereducer
- Keep Reducer Functions Pure: Avoid side effects in the reducer. It should only return the new state based on the current state and action.
- Use Action Constants: Instead of using string literals for action types, define them as constants to avoid errors due to typos.
- Avoid Overusing useReducer(): For simple state, useState() might be easier to manage. Don’t overcomplicate things with useReducer() when it’s unnecessary.
Conclusion
react native usereducer is a valuable tool for managing state, especially for complex applications with intricate state logic. It allows you to structure and centralize your state management, making your code more predictable, easier to debug, and scalable. While it may seem more complex than useState(), it offers greater control over state transitions, making it ideal for managing multiple or complex state values. With the examples and best practices shared in this guide, you’re ready to start implementing useReducer() in your own React applications!
