Alan
Alan

Reputation: 11

ReactJS set array data

I want to ask: Why userPost is empty?

function Feed() {
  const [userPost, setUserPost] = useState([]);
  useEffect(() => {
    const userId = localStorage.getItem("userID");
    const getUserPost = () => {
      axios
        .get(`http://localhost:5000/api/posts/profile/${userId}`)
        .then((res) => {
          console.log(res.data.posts);
          setUserPost(res.data.posts);
          console.log(userPost);
        })
        .catch((err) => {
          console.log(err.response);
        });
    };
    getUserPost();
  }, []);

  console.log(userPost);

  return (<></>)
}

Result: console.log(res.data.posts)

(3) [{…}, {…}, {…}]
0: {_id: '6220c9c7c1750a6ec3618165', userId: {…}, …}
1: {_id: '6220d26dc1750a6ec36181a7', userId: {…}, …}
2: {_id: '6221de326c2cc78a2b758a63', userId: {…}, …}
length: 3
[[Prototype]]: Array(0)

Result: console.log(userPost)

[]
length: 0
[[Prototype]]: Array(0)

Thanks.

Upvotes: 1

Views: 420

Answers (3)

Nick Vu
Nick Vu

Reputation: 15520

useState is asynchronous, so that's why when you try to call console.log(userPost); instantly after setUserPost(res.data.posts);, userPost has not been updated yet.

If you want to understand more, you can read this article

https://dev.to/shareef/react-usestate-hook-is-asynchronous-1hia

Upvotes: 0

Mehdi Namvar
Mehdi Namvar

Reputation: 1151

Actually, it's not empty! Setting state in React is not a sync function, it's async. You're logging the state before it is changed. If you log the userPost in the body of your component function, you will see the items are there.

function Feed() {
  const [userPost, setUserPost] = useState([]);

  useEffect(() => {
    const userId = localStorage.getItem("userID");
    const getUserPost = () => {
      axios
        .get(`http://localhost:5000/api/posts/profile/${userId}`)
        .then((res) => {
          setUserPost(res.data.posts);
        })
        .catch((err) => {
          console.log(err.response);
        });
    };
    getUserPost();
  }, []);

  // LOG HERE
  console.log(userPost);
}

Upvotes: 0

Amila Senadheera
Amila Senadheera

Reputation: 13245

The issue is setUserPost is an asynchronous operation. Therefore you cannot expect it to log right after the setter method.

setUserPost(res.data.posts);
console.log(userPost);

If you want to see the updated userPost value add the log to the method body of the Feed component. (Because Feed gets invoked when a state of the component updates)

function Feed() {
  const [userPost, setUserPost] = useState([]);
  useEffect(() => {
    const userId = localStorage.getItem("userID");
    const getUserPost = () => {
      axios
        .get(`http://localhost:5000/api/posts/profile/${userId}`)
        .then((res) => {
          setUserPost(res.data.posts);
        })
        .catch((err) => {
          console.log(err.response);
        });
    };
    getUserPost();
  }, []);

  console.log(userPost);

  return <></>;
}

Upvotes: 1

Related Questions