【问题标题】:Reactjs : TypeError: Cannot read property 'map' of undefinedReactjs:TypeError:无法读取未定义的属性“地图”
【发布时间】:2021-06-03 16:45:53
【问题描述】:

我一直在从事那个 React 项目,并且一直在使用 axios 从我的后端获取数据。我多次收到 (TypeError: Cannot read property 'map' of undefined) 错误,我尝试了多次修复,但没有希望修复。我添加了一个用于加载的钩子,以确保在渲染之前存在数据,但是如果我在页面之间返回和第四次,我会收到相同的错误

这是我的代码:

function Developer(props) {
    const [data, setData] = useState();
    const [loading , setLoading] = useState(true)
    const [error, setError] = useState();

    var id = props.match.params.id
    var location = props.match.params.location


    useEffect(() => {
        axios(`http://localhost:5000/api/${location}/${id}`)
        .then((response) => {
        setData(response.data);
        })
        .catch((error) => {
        console.error("Error fetching data: ", error);
        setError(error);
        })
        .finally(() => {
        setLoading(false);
        });
        }, []);
        
    if (loading) return "Loading...";
    if (error) return "Error!";

    return (
        <div>
            <h1>{data.Developer}</h1>
            <ul>
                {
                data.Projects.map((project) => (<li key = {project._id}>
                <a href= {`/${location}/${id}/${project._id}`}>{project.Project}</a></li> ))
                }
            </ul>
        </div> 
        )}

【问题讨论】:

  • data.Projects 未定义。我们能看到 api 调用的响应是什么样的吗?此外,您似乎没有在 api 调用之前将加载变量设置为 true。因此,您可能需要检查 jsx 中是否未定义数据。基本上看起来正在发生的是你试图循环一个未定义的变量,但你没有告诉视图等到数据被获取。加载变量将在 axios 调用之前为您 setLoading(true) 执行此操作。然后在 setData 之前 setLoading(false)。
  • data.Projects 是 axios 调用返回的集合的一部分,因此它存在。我真的不知道何时将加载变量设置为 true 以及何时设置为 false。你能解释一下吗

标签: javascript node.js reactjs


【解决方案1】:

在制作地图之前,您应该检查数据属性的性质。

{
 data && data.Projects.length !== 0 &&
   data.Projects.map((project) => (<li key = {project._id}>
    <a href= {`/${location}/${id}/${project._id}`}>{project.Project}</a></li> ))
}

我建议你使用 javascrip fetch

【讨论】:

  • 如果data.Projects 不是数组,这仍然会出错。
  • 因为 Projects 不是数组。您可以记录数据。项目以查看项目的类型。 console.log(data.Projects);
【解决方案2】:

我自己也遇到过很多次这个错误。

首先检查您从 api 获取的数据是否是 javascript 对象数组

这是一个简单的解决方案。

{data ? data.Projects.map((project) => (<li key={project._id}>
                    <a href={`/${location}/${id}/${project._id}`}>{project.Project}</a></li>)) :<div>Loading..</div>}

所以我在这里所做的是使用三元运算符,它会检查数据状态是否有数据,如果有它将显示数据,否则它将显示“正在加载...”

Axios 需要一些时间来获取和设置数据,但页面在此之前呈现,所以它显示无法读取未定义的属性 'map'

【讨论】:

  • 有可能定义了data,但没有定义data.Projects,并且您的解决方案告诉用户它仍在加载,虽然它已经完成并且数据丢失了。这会产生误导。
【解决方案3】:

返回的数据可能不包含您需要的内容。

尝试打印出返回的数据

        axios(`http://localhost:5000/api/${location}/${id}`)
        .then((response) => {
          console.log(response.data);
          setData(response.data);
        })

它可能是一个有效的响应,但不包含该变量data.Projects。如果您想处理该值的缺失,您可以使用类似:

(data.Projects || []).map(...)

这样,如果data.Projects 是假的,它将被一个空数组替换并调用[].map(...)

【讨论】:

    【解决方案4】:

    如上所述,您的 setLoading(true) 要求。

    function Developer(props) {
        const [data, setData] = useState();
        const [loading , setLoading] = useState(true)
        const [error, setError] = useState();
    
        var id = props.match.params.id
        var location = props.match.params.location
    
    
        useEffect(() => {
           // ooh look, we are in a loading state here, cause the data hasn't come back from the server at this point.
     setLoading(true);
            axios(`http://localhost:5000/api/${location}/${id}`)
               .then((response) => {
               setData(response.data);
               // awesome, data has returned from the server, we aren't loading anymore, but the finally block handles that scenario for us.
    
            })
            .catch((error) => {
              console.error("Error fetching data: ", error);
              setError(error);
            })
            .finally(() => {
              setLoading(false);
            });
            }, []);
            
        if (loading) return "Loading...";
        if (error) return "Error!";
    
        return (
            <div>
                <h1>{data.Developer}</h1>
                <ul>
                    {
                    data && data.Projects.length && data.Projects.map((project) => (<li key = {project._id}>
                    <a href= {`/${location}/${id}/${project._id}`}>{project.Project}</a></li> ))
                    }
                </ul>
            </div> 
            )}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多