Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks - useState() is not re-rendering the UI with the new state updates

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.

like image 891
MoSwilam Avatar asked Feb 02 '19 17:02

MoSwilam


People also ask

Why does the React useState hook not update immediately?

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.

Does useState hook re-render?

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.

Why is my React component not re rendering?

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.

Does React Rerender on state change?

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.


1 Answers

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)
     })
   }, [])
thanks :)
like image 53
MoSwilam Avatar answered Oct 16 '22 06:10

MoSwilam