I’m new to react so bare with me. I’m trying to update my todo task using the post request. however when I click on the submit button it submits an empty array and not the title or detail that was inputted.
import {useEffect , useState } from 'react'
function Activities(){
const [todo , setTodo] = useState([]);
const [title, setTitle] = useState ('');
const [detail, setDetail] = useState ('')
function loadActivity() {
fetch("https://5ff86cfb10778b0017043497.mockapi.io/todos")
.then((response) => response.json ())
.then((data) => setTodo(data));
}
const handleSubmit = (e) => {
e.preventDefault();
const task = {title, detail};
fetch('https://5ff86cfb10778b0017043497.mockapi.io/todos', {
method: 'POST',
headers: { "content-Type": "applicaton/json" },
body: JSON.stringify(task)
}).then(() => {
console.log(todo);
})
}
useEffect (() => {loadActivity()} , [] );
return (
<>
<div>
<p>
{todo.map(todo=> (
<ul>
<li key = {todo.id}> title = {todo.title}</li>
<li key = {todo.detail}> details = {todo.detail} </li>
</ul>
))}
</p>
<div className = "create">
<form onSubmit = {handleSubmit}>
<input type ="text"
required
value ={title}
onChange={(e) => setTitle(e.target.value)}/>
<input type = "text"
value = {detail}
required
onChange = {(e) => setDetail(e.target.value)}/>
<button type = "submit">add todo!</button>
</form>
</div>
</div>
</>
)
}
export default Activities
The other file:
export default function DataFetching() {
return (
<>
<Activities/>
</>
)
}
I fetch the data from the api succesfully however when I try to add a title or description, it doesnt get stored but instead an empty object.
why is this?
>Solution :
You are not adding the new todo to your state (with setTodo). You can do this either:
When your POST request is resolved (right where you console.log it now)
fetch('https://5ff86cfb10778b0017043497.mockapi.io/todos', {
method: 'POST',
headers: { "content-Type": "applicaton/json" },
body: JSON.stringify(task)
}).then(() => {
console.log(todo);
setTodo(todos => [...todos, task]);
});
If your server response contains the newly set data – indicated with newTodo parameter – you can use it to update your state instead of the task, that you constructed yourself. That might be the best approach, beacuse you are sure that your React app state is perfectly in sync with your server.
Beware that if you are using Fetch API, you would need to JSON.parse the response first before you can use it:
fetch('https://5ff86cfb10778b0017043497.mockapi.io/todos', {
method: 'POST',
headers: { "content-Type": "applicaton/json" },
body: JSON.stringify(task)
})
.then(response => JSON.parse(response))
.then(newTodo => {
setTodo(todos => [...todos, newTodo]);
});
An alternative approach would be to update the state right away (so called "optimistically"), without waiting for the server response. In such case you can call setTodo before or after your fetch call. However, the first suggestion (update state after POST request resolves) is better, because if you update optimistically and the request fails and throws an error, you will have conflict between your React app state and the state on your API server.