Reputation: 1111
I am making a todo app to sharpen my react skills with hooks and I want to make a function updateTask to update the currently selected task with whatever I type in the input after the getCurrentTask function is triggered, which populates the input value with the currently selected task's text value.
This is the updateTask function:
function updateTask(statePlaceholder, id) {
const updatedTaskIndex = statePlaceholder.tasks.findIndex(
task => task.id === id
);
const updatedTask = statePlaceholder.tasks.map(task => {
return { ...task, text: statePlaceholder.currentTask.text };
});
const updatedTasks = [
...statePlaceholder.tasks.slice(0, updatedTaskIndex),
updatedTask,
...statePlaceholder.tasks.slice(updatedTaskIndex + 1)
];
return {
...statePlaceholder,
tasks: updatedTasks,
currentTask: null
};
}
and I use this function in the handleSubmit function in the form
function handleSubmit(e) {
e.preventDefault();
state.currentTask
? setState(updateTask(state, state.currentTask.id))
: setState(createTask(state, value));
setValue("");
}
I want to be able to update the currently selected task.
Upvotes: 0
Views: 398
Reputation: 1909
There are is an error in your updateTask
function, but before coming to that there is a suggestion.
Looks like you are using composite state, like
[state, setState] = useState({tasks:[], current:0})
Instead more idiomatic way is to use separate state variables:
[tasks, setTasks] = useState([]);
[current, setCurrent] = useState(0);
This will also make your state management much more easier.
Now coming back to error in updateState
, after retrieving updatedTaskIndex
, you need to 1) retrieve the originalTask
, 2) mutate it and 3) put it back in right position in new array. You are not doing #1 and hence #2 you are attempting will produce wrong result. Do something like
origTask = tasks[taskIndex];
updatedTask = {...origTask, text: text}
Upvotes: 1
Reputation: 10304
The logic of your code is basically returning a collection of updates tasks.
And then the problem is that you're having duplicate keys in your statePlaceholder.tasks list
Why you need to replace the text in all your statePlaceholder.tasks,
It seems that you are returning an array here (many tasks and not just one task) so this causes later on the duplicate keys error
const updatedTask = statePlaceholder.tasks.map(task => {
return { ...task, text: statePlaceholder.currentTask.text };
});
its better that change to:
const updatedTask = statePlaceholder.tasks.filter(task => task.id === id)
updatedTask.text= statePlaceholder.currentTask.text;
const updatedTasks = [
...statePlaceholder.tasks.slice(0, updatedTaskIndex),
updatedTask,
...statePlaceholder.tasks.slice(updatedTaskIndex + 1)
];
so I looked at your code posted at the sandbox and the problem is that function updateTask(statePlaceholder, id)
parameter id is arriving as undefined, and then updatedTaskIndex -> -1
You are only setting the name of the task and not the object(with the id) here:
<input
type="text"
className="App_input"
placeholder="Type Task"
value={value}
onChange={e => setValue(e.target.value)}
/>
Upvotes: 0