I'm new to react and tying in the back end but after I make the fetch requests, I have to reload the page to see any changes. The database is updated as soon as the functions are called but the ponent doesn't re-render. I know setState works asynchronously, so I tried calling my functions in the callback of setState but that did not work.
This happens on both my handleSubmit
and handleDelete
functions. My initial get request is in my ponentDidMount so I'm including that in case it helps.
I couldn't find the answer that I needed on the site, maybe the remendations were just off but here I am, lol. Thanks in advance.
ponentDidMount() {
// todos is the data we get back
// setting the state to newly aquired data
fetch("/api/todos")`enter code here`
.then(res => res.json())
.then(todos => this.setState({ todos }, () =>
console.log("Todos fetched...", todos)))
.catch(err => console.log(err))
}
// onClick for submit button
handleSubmit = (e) => {
e.preventDefault();
const data = this.state;
fetch("/api/todos", {
method: "post",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
};
// onClick for delete button
handleDelete = (e) => {
e.preventDefault();
let uniqueId = e.target.getAttribute("id")
fetch(`/api/todos/${uniqueId}`, {
method: "delete",
headers: { 'Content-Type': 'application/json' }
})
};
// Some of the JSX if needed
<DeleteBtn
id={todo._id}
onClick={this.handleDelete}
>X</DeleteBtn>
<Form onSubmit={this.handleSubmit} id="myForm"></Form>
<script src=".6.3/umd/react.production.min.js"></script>
<script src=".6.3/umd/react-dom.production.min.js"></script>
I'm new to react and tying in the back end but after I make the fetch requests, I have to reload the page to see any changes. The database is updated as soon as the functions are called but the ponent doesn't re-render. I know setState works asynchronously, so I tried calling my functions in the callback of setState but that did not work.
This happens on both my handleSubmit
and handleDelete
functions. My initial get request is in my ponentDidMount so I'm including that in case it helps.
I couldn't find the answer that I needed on the site, maybe the remendations were just off but here I am, lol. Thanks in advance.
ponentDidMount() {
// todos is the data we get back
// setting the state to newly aquired data
fetch("/api/todos")`enter code here`
.then(res => res.json())
.then(todos => this.setState({ todos }, () =>
console.log("Todos fetched...", todos)))
.catch(err => console.log(err))
}
// onClick for submit button
handleSubmit = (e) => {
e.preventDefault();
const data = this.state;
fetch("/api/todos", {
method: "post",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
};
// onClick for delete button
handleDelete = (e) => {
e.preventDefault();
let uniqueId = e.target.getAttribute("id")
fetch(`/api/todos/${uniqueId}`, {
method: "delete",
headers: { 'Content-Type': 'application/json' }
})
};
// Some of the JSX if needed
<DeleteBtn
id={todo._id}
onClick={this.handleDelete}
>X</DeleteBtn>
<Form onSubmit={this.handleSubmit} id="myForm"></Form>
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
The result I'm looking for is once I add a todo, for it to render on my list immediately, rather than only upon page reload.
Share Improve this question asked Sep 10, 2019 at 14:20 Jacob BroughtonJacob Broughton 4222 gold badges6 silver badges16 bronze badges 2- Are you sure about class ponent? I would suggest to start smoothly moving to functional ponents and hooks. – Pencroff Commented Jul 5, 2021 at 11:09
- This was a while ago, i use hooks / functional ponents now – Jacob Broughton Commented Jul 5, 2021 at 14:28
3 Answers
Reset to default 0Return the details from the back-end in the requests, use that values to update the state,
Currently you just perform the operation on the back-end and front-end doesn't know that it happened in the back-end. The Best way is to either pass the full data(list or object) back to front-end after operation performed on the DB and link the values to a state, if the data is bulk then send a success message(200 is enough) back from back-end to front-end and if success change the value(list) in front-end, Link the value(list) to a state in front-end to have a re rendering of the ponent.
you've to update your state, and once you'll update the state your ponent will re-render and it'll shows the latest changes. Here i am assuming "todos" you've set in your state is an array, then just update it on deleting and adding. i.e:
// onClick for submit button
handleSubmit = (e) => {
e.preventDefault();
const data = this.state;
const currentTodos = [...this.state.todos]
fetch("/api/todos", {
method: "post",
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}).then(()=>{
currentTodos.push(data);
this.setState({todos:currentTodos})
})
};
// similarly for delete you can do
// onClick for delete button
handleDelete = (e) => {
e.preventDefault();
let uniqueId = e.target.getAttribute("id")
let currentTodos = [...this.state.todos];
fetch(`/api/todos/${uniqueId}`, {
method: "delete",
headers: { 'Content-Type': 'application/json' }
}).then(()=>{
let updatedTodos = currentTodos.filter(todo=>todo._id !==uniqueId);
this.setState({todos:updatedTodos})
})
};
You are probably not changing your state "todos" that is why it doesn't render. You could fetch todos after every change (after remove, update, add...) or change the state yourself.
Methode 1:
ponentDidMount() {
this.getTodos();
}
getTodos = () => {
//fetch todos, setState
}
handleSubmit = () => {
fetch(...).then(this.getTodos);
}
handleDelete = () => {
fetch(...).then(this.getTodos);
}
Methode 2:
ponentDidMount() {
this.getTodos();
}
getTodos = () => {
//fetch todos, setState
}
handleSubmit = () => {
fetch(...);
let todos = this.state.todos;
todos.push(newTodo);
this.setState({todos});
}
handleDelete = () => {
fetch(...);
let todos = this.state.todos;
//remove todo from todos
this.setState({todos});
}