I am trying out the new React Hooks, and I am a little stuck as the UI is not updating when the local state is updated. Here is my code,
import React, { useState, useEffect } from 'react';
import Post from './Post'
import PostForm from './PostForm';
import axios from 'axios';
function PostsList() {
const [posts, setPosts] = useState([]);
// setting up the local state using useEffect as an alternative to CDM
useEffect(() => {
axios.get('...')
.then(res => {
// the resposne is an array of objects
setPosts(res.data)
})
})
const handleSubmit = (data) => {
// the data I am getting here is an object with an identical format to the objects in the posts array
axios.post('...', data)
.then(res => {
// logging the data to validate its format. works fine so far..
console.log(res.data);
// the issue is down here
setPosts([
...posts,
res.data
])
})
.catch(err => console.log(err))
}
return (
<div>
<PostForm handleSubmit={handleSubmit} />
<h3>current posts</h3>
{ posts.map(post => (
<Post key={post.id} post={post} />
)) }
</div>
)
}
when I submit the form, the UI flickers for a split second and then renders the current state without the new update, it seems that something is preventing it from re-rendering the new state. If more code/clarification is needed please leave a comment below. thanks in advance.
The answer: They're just queues setState , and React. useState create queues for React core to update the state object of a React component. So the process to update React state is asynchronous for performance reasons. That's why changes don't feel immediate.
The useState() hook in react allows us to declare a state variable that persists during the re-render cycles. If we want to re-render the component then we can easily do so by calling the setState() function which is obtained by destructuring the array returned as a result of calling the useState() hook.
If React fails to do re-render components automatically, it's likely that an underlying issue in your project is preventing the components from updating correctly.
React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.
alright, problem solved with the helpful hint from @skyboyer,
so what happened initially is, the useEffect()
acts like componentDidMount()
& componentDidUpdate()
at the same time, that means whenever there is an update to the state, the useEffect()
gets invoked, which means resetting the state with the initial data coming from the server.
to fix the issue I needed to make the useEffect()
renders the component only one time when it's created/rendered as opposed to rendering it every time there is an update to the state. and this is done by adding an empty array as a second argument to the useEffect()
function. as shown below.
useEffect(() => {
axios.get('...')
.then(res => {
setPosts(res.data)
})
}, [])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With