Todos Component:
import React, { useReducer, useState } from 'react';
import Todo2 from './Todo2';
export const ACTIONS = {
ADD_TODO : 'add-todo',
TOGGLE_TODO : 'toggle-todo'
};
function reducer(state, action) {
switch(action.type) {
case ACTIONS.ADD_TODO:
return [...state, {id: Date.now(), name: action.payload.name, complete: false}];
case ACTIONS.TOGGLE_TODO:
const patch = [...state];
console.log('The index is:', action.payload.index);
console.log('The current state is:', patch[action.payload.index].complete);
// update state
patch[action.payload.index].complete = !patch[action.payload.index].complete;
console.log('The updated state is:', patch[action.payload.index].complete);
console.log('The patch is:', patch);
return patch;
}
}
export default function Todos() {
const [todos, dispatch] = useReducer(reducer, []);
const [name, setName] = useState('');
function handleSubmit(e) {
e.preventDefault();
dispatch({type: ACTIONS.ADD_TODO, payload: {name: name}});
setName('');
}
return (
<div>
<form onSubmit={handleSubmit}>
<input type="text" value={name} onChange={e => setName(e.target.value)}/>
</form>
{todos.map((todo, i) => <Todo2 key={todo.id} todo={todo} index={i} dispatch={dispatch} />)}
</div>
);
}
Todo Component:
import React from 'react';
import { ACTIONS } from './Todos2';
export default function Todo2({ todo, dispatch, index }) {
return (
<div>
<span style={{color: todo.complete ? 'green':'red' }}>{todo.name}</span>
<button onClick={e => dispatch({type: ACTIONS.TOGGLE_TODO, payload : {index: index}})}>Toggle</button>
</div>
)
}
I am trying to update an object inside an array, setting its "complete" property to either true or false depending on its current value. I console.logged the results but in the end the patch never gets it's updated data, it always retains it's original value.
If I update the state like this, it works and I don't know why this works but the index way of updating does not.
// update state
patch[action.payload.index].complete = true;