JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://wzrd.in/standalone/expect@latest"></script>
<script src="https://wzrd.in/standalone/deep-freeze@latest"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.4.4/babel.min.js"></script>

JavaScript

// Individual TODO Reducer
const todoReducer = (state, action) => {
	switch(action.type) {
  	case 'ADD_TODO':
    	return {
          	id: action.id,
            text: action.text,
            completed: false
          };
    case 'TOGGLE_TODO':
    	if (state.id != action.id) return state;
          
      // This not working
      /*
      return {
        ...state,
        completed: !state.completed
      };
      */
      
      //This works
      var newState = {id: state.id, text: state.text, completed: !state.completed};
      return newState;
    default:
    	return state;
  }
};

//TODOS Reducer
const todos = (state = [], action) => {
		switch(action.type) {
    	case 'ADD_TODO':
       return [
          ...state,
          todoReducer(null, action)
       ];
       case 'TOGGLE_TODO':
       	return state.map(t => todoReducer(t, action));
      default:
      	return state;
    }
};

//Test 1
const testAddTodo = () => {
  const stateBefore = [];
  
  const action = {
      type: 'ADD_TODO',
      id: 0,
      text: 'Learn Redux'
  };
  
  const stateAfter = [{
     id: 0,
     text: "Learn Redux",
     completed: false
  }];
  
  //Freeze
  deepFreeze(stateBefore);
  deepFreeze(action);
  
  // Test
  expect(
     todos(stateBefore, action)
  ).toEqual(stateAfter);
};

//Test 2
const testToggleTodo = () => {
  const stateBefore = [{id: 0,
     text: "Learn Redux",
     completed: false
  }, {
  	id: 1,
    text: "Go Shopping",
    completed: false
  }];
  
  const action = {
      type: 'TOGGLE_TODO',
      id: 1
  };
  
  const stateAfter = [{
     id: 0,
     text: "Learn Redux",
     completed: false
  }, {
  	id: 1,
    text: "Go Shopping",
    completed: true
  }];
  
  //Freeze
  deepFreeze(stateBefore);
  deepFreeze(action);
  
  // Expect
  expect(
     todos(stateBefore, action)
  ).toEqual(stateAfter);
};

testAddTodo();
testToggleTodo();
console.log("All tests passed");