Blog>
Snippets

Immutable state updates in reducers with Object.create(null)

Showcase how to perform immutable state updates in reducers using Object.create(null) for state comparisons.
<!DOCTYPE html>
<html>
<head>
<style>
  body {
    font-family: Arial, sans-serif;
  }
</style>
</head>
<body>

<div id="app">
  <p>Count: <span id="counter-value">0</span></p>
  <button id="increment-btn">Increment</button>
</div>

<script>
  // Define the initial state
  const initialState = Object.create(null);
  initialState.count = 0;

  // Define the reducer function
  function counterReducer(state, action) {
    switch (action.type) {
      case 'INCREMENT':
        // Return a new state object with an incremented count
        const newState = Object.create(null);
        newState.count = state.count + 1;
        return newState;
      default:
        return state;
    }
  }

  // Update the UI
  function updateUI(count) {
    document.getElementById('counter-value').textContent = count;
  }

  // Dispatch an action
  function dispatch(action) {
    // Reducer updates the state immutably
    state = counterReducer(state, action);
    updateUI(state.count);
  }

  // Initial render
  let state = initialState;
  updateUI(state.count);

  // Increment button event listener
  document.getElementById('increment-btn').addEventListener('click', function() {
    dispatch({ type: 'INCREMENT' });
  });
</script>

</body>
</html>
This HTML document includes inline CSS and JavaScript. It contains a simple UI with a counter and an increment button. The 'counterReducer' function manages the state, ensuring that each update is immutable by using 'Object.create(null)' to create a new state object instead of mutating the existing one. The 'dispatch' function applies the reducer's logic to update the state and subsequently calls 'updateUI' to reflect the state changes on the page. Initial state and UI updates are performed on initial render, and an event listener is attached to the increment button to dispatch the increment action.