Tech

Build Redux: Guide to State Management Mastery

Redux solves a big problem: managing state. State means data your app uses, like user info, loading status, or

Build Redux: Guide to State Management Mastery

Redux solves a big problem: managing state. State means data your app uses, like user info, loading status, or form inputs. As apps grow, state gets messy.

Redux keeps state organized in one central place. Think of it like a single notebook holding all app data. Every part of your app reads from this notebook. When changes happen, they update the notebook. No more lost data or confusing connections.

Why Build Redux Yourself?

Building Redux teaches you its magic. You’ll understand:

  • How state updates safely
  • Why changes are predictable
  • What makes Redux reliable
    This knowledge helps you debug apps faster and write cleaner code. Plus, you’ll appreciate libraries more when you see their inner workings.

Core Ideas Behind Redux

Redux stands on three rules:

  1. Single Source of Truth: All state lives in one object called the store.
  2. State is Read-Only: You can’t change state directly. Instead, you describe changes with plain objects called actions.
  3. Changes with Pure Functions: A function called a reducer takes the current state and an action, then returns the new state.

Building the Redux Store

The store holds your state and handles updates. Here’s how to build it:

javascript

function createStore(reducer) {  
  let state;  
  let listeners = [];  

  const getState = () => state;  

  const dispatch = (action) => {  
    state = reducer(state, action);  
    listeners.forEach(listener => listener());  
  };  

  const subscribe = (listener) => {  
    listeners.push(listener);  
    return () => {  
      listeners = listeners.filter(l => l !== listener);  
    };  
  };  

  // Initialize state  
  dispatch({ type: '@@INIT' });  

  return { getState, dispatch, subscribe };  
}  
  • getState: Lets you read the current state.
  • dispatch: Takes an action, runs it through the reducer to update state, then notifies listeners.
  • subscribe: Adds functions (listeners) that trigger when state changes.

Creating Actions and Reducers

Actions are simple objects with a type (like “ADD_TODO”) and optional data:

javascript

{ type: 'ADD_TODO', text: 'Learn Redux' }  

Reducers are pure functions that handle state changes:

javascript

function todoReducer(state = [], action) {  
  switch (action.type) {  
    case 'ADD_TODO':  
      return [...state, { text: action.text, completed: false }];  
    case 'TOGGLE_TODO':  
      return state.map((todo, index) =>  
        index === action.index   
          ? { ...todo, completed: !todo.completed }  
          : todo  
      );  
    default:  
      return state;  
  }  
}  

Rules for reducers:

  • Never change state directly. Create new copies.
  • Return unchanged state for unknown actions.

Connecting Redux to React

Link your store to components using Provider and connect:

  1. Wrap your app with Provider:

jsx

import { Provider } from 'react-redux';  

ReactDOM.render(  
  <Provider store={store}>  
    <App />  
  </Provider>,  
  document.getElementById('root')  
);  
  1. Connect components:

jsx

import { connect } from 'react-redux';  

const TodoList = ({ todos, addTodo }) => (  
  // Component uses todos and addTodo from props  
);  

const mapStateToProps = state => ({  
  todos: state.todos  
});  

const mapDispatchToProps = dispatch => ({  
  addTodo: text => dispatch({ type: 'ADD_TODO', text })  
});  

export default connect(mapStateToProps, mapDispatchToProps)(TodoList);  

Adding Middleware

Middleware lets you run code between dispatch and the reducer. Use it for logging, async calls, or error tracking.

Build a logger middleware:

javascript

const logger = store => next => action => {  
  console.log('Dispatching:', action);  
  let result = next(action);  
  console.log('New state:', store.getState());  
  return result;  
};  

Apply middleware to your store:

javascript

function applyMiddleware(...middlewares) {  
  return createStore => (reducer, initialState) => {  
    const store = createStore(reducer, initialState);  
    let dispatch = store.dispatch;  

    middlewares.forEach(middleware => {  
      dispatch = middleware(store)(dispatch);  
    });  

    return { ...store, dispatch };  
  };  
}  

// Create store with middleware  
const store = createStore(  
  reducer,  
  applyMiddleware(logger)  
);  

Testing Your Redux Code

Test key parts:

  • Reducers: Check if they handle actions correctly.

javascript

test('ADD_TODO adds a new todo', () => {  
  const stateBefore = [];  
  const action = { type: 'ADD_TODO', text: 'Test' };  
  const stateAfter = [{ text: 'Test', completed: false }];  

  expect(todoReducer(stateBefore, action)).toEqual(stateAfter);  
});  
  • Actions: Verify they create the right objects.
  • Middleware: Ensure they process actions properly.

Common Mistakes and Fixes

  1. Mutating State:
    Wrong: state.todos.push(newTodo)
    Right: return [...state.todos, newTodo]
    Fix: Always copy arrays/objects before changing them.
  2. Forgetting Default Case in Reducers:
    Always return state for unknown actions.
  3. Overcomplicating Actions:
    Keep actions focused. Use multiple simple actions instead of one giant action.
  4. Too Much State in Redux:
    Don’t put all component state in Redux. Use it only for data shared across your app.
  5. Async Action Issues:
    Use middleware like redux-thunk for async logic:javascriptCopyDownloadconst fetchData = () => dispatch => { dispatch({ type: ‘FETCH_START’ }); fetch(‘/data’).then(res => res.json()).then(data => { dispatch({ type: ‘FETCH_SUCCESS’, data }); }); };

By building Redux yourself, you gain control over state management. You’ll write apps that are easier to maintain, scale, and debug. Start small, test often, and keep your state predictable.

About Author

Felix Pembroke

Felix Pembroke is a UK-based tech enthusiast and the author behind TechImaging.co.uk. With a keen eye for innovation and a passion for simplifying complex technology, Felix provides insightful content that helps readers stay informed and ahead of the tech curve. Felix also covers general content, making TechImaging.co.uk a versatile source for a broad range of topics.

Leave a Reply