简体   繁体   English

map 无法在 React 中首次渲染时获取数据

[英]Can't map fetched data on first render in React

I have an API that returns me 4 objects and I try to save them in a new array called "products" and map them to the DOM.我有一个 API 返回我 4 个对象,我尝试将它们保存在一个名为“产品”的新数组中,并将 map 保存到 DOM。 My problem is that map function doesn't work on first render.我的问题是 map function 在第一次渲染时不起作用。

If I modify something in my code, save the file and watch the react page again, I will see that my data appeared.如果我修改代码中的某些内容,保存文件并再次查看 React 页面,我会看到我的数据出现了。

How can I fix that?我该如何解决?

import { useEffect, useState } from 'react';
import './App.css';

function App() {

  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch("URL")
    .then(res => res.json())
    .then(data => {
      for(let i = 0; i < data.length; i++) {
        products.push(data[i])
      }
    })
  })

  console.log(products);

  return (
    <div className="App">
      {products.map((product,index) => (
        <div key={index}>{product.price}</div>
      ))}
    </div>
  );
}

export default App;

const [products, setProducts] = useState([]);

useEffect(() => {
    async function getdata() {      
      const res = await fetch("URL");
      const data = await res.json();
      setProducts(data)
    }

    let unmounted = false;    
    if (!unmounted) {
      getdata();
    }

    return () => unmounted = true;
}, []);

You can try this, I hope It will be work.你可以试试这个,我希望它会起作用。

You're directly mutating state which is a React no-no.你直接改变 state 这是 React 的禁忌。

You need to use the setProducts state setter instead您需要改用setProducts state setter

useEffect(() => {
  fetch("URL")
    .then(async res => {
      if (!res.ok) { // don't forget to check for errors
        throw new Error(`${res.status}: ${await res.text()}`);
      }
      return res.json();
    })
    .then(setProducts) // pass the resolved data to the state setter
    .catch(console.error);
}, []); // use an empty dependency array to only run once on mount

Here's a demo using the JSONPlaceholder /albums API这是一个使用JSONPlaceholder /albums API 的演示

编辑 romantic-galois-0jvkzt

First of all, you are missing dependency array in your useEffect hook.首先,您在useEffect挂钩中缺少依赖数组。 Assuming you want the useEffect hook to run on initial render, I am passing empty dependency array ( [] ).假设您希望useEffect挂钩在初始渲染时运行,我将传递空依赖项数组 ( [] )。

Next fix is you wait for your data to be set in products, and if products are set (that is you have a products.length > 0 ), you call下一个修复是您等待在产品中设置数据,如果设置了产品(即您有products.length > 0 ),则调用

useEffect(() => {
    fetch("URL")
    .then(res => res.json())
    .then(data => setProducts(data))
  }, [])

  console.log(products);

  return (
    <div className="App">
      {products.length && products.map((product,index) => (
        <div key={index}>{product.price}</div>
      ))}
    </div>
  );

you have to run useEffect() only once then u need to call setProducts您只需运行一次 useEffect() 然后您需要调用 setProducts

useEffect(() => {
    fetch("URL")
      .then(res => res.json())
      .then(data => {
        setProducts(data);
      })
  },[])

The data is fetched after the first render.第一次渲染后获取数据。 You might want to use你可能想使用

{Boolean(products.length) && products.map((product,index) => (
    <div key={index}>{product.price}</div>
  ))}

and

useEffect(() => {
fetch("URL")
.then(res => res.json())
.then(data => {
  for(let i = 0; i < data.length; i++) {
    products.push(data[i])
  }
  setProducts(products);
})
})

instead反而

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM