开发者问题收集

未捕获的类型错误:无法在 React 前端读取未定义的属性(读取“名称”)

2024-02-26
97

我试图从我从后端 bust 获取对象数组后获得的对象中访问对象的属性,当我尝试访问该属性时,它会将对象本身记录为未定义,如果我从未在控制台中访问该属性,则会成功记录。

这是代码,我注释了错误的位置:

import { useEffect, useState } from "react";
import toast from "react-hot-toast";


const useGetConversations = () => {
    const [loading, setLoading] = useState(false);
    const [conversations, setConversations] = useState([]);

    useEffect(() => {
        const getConversations = async () => {
            setLoading(true);
            try {
                const res = await fetch("/api/users");
                const data = await res.json();
                if (data.error) {
                    throw new Error(data.error);
                }
                
                setConversations(data);
                
            } catch (error) {
                toast.error(error.message);
            } finally {
                setLoading(false);
                
            }
        };

        getConversations();
    }, []);
    console.log("before return statement",conversations[0]);// it runs correctly only if i am not trying to acces any property
    console.log("before return statement",conversations[0].name);
    return { loading, conversations };
    
};
export default useGetConversations;

这是错误截图:

在此处输入图像描述

我希望成功运行文件:

import useGetConversations from "../../hooks/useGetConversations";
import { getRandomEmoji } from "../../utils/emojis";
import Conversation from "./Conversation";

const Conversations = () => {
    const { loading, conversations } = useGetConversations();

    //could log the array of objects succesfully
    // console.log(conversations);
    //could log a single object successfully
    // console.log(conversations[0]); 
    //could not log the object properties successfully and previous lines are also defined as undefined 
    // console.log(conversations[0].name); 
    return (
        <div className='py-2 flex flex-col overflow-auto'>
            {conversations.map((conversation, idx) => (
                <Conversation
                    key={conversation._id}
                    conversation={conversation}
                    emoji={getRandomEmoji()}
                    lastIdx={idx === conversations.length - 1}
                />
            ))}

            {loading ? <span className='loading loading-spinner mx-auto'></span> : null}
        </div>
    );
};
export default Conversations;
2个回答

处理嵌套对象或访问 API 调用返回的对象的属性时,使用可选链接(?)进行访问。

import { useEffect, useState } from "react";
import toast from "react-hot-toast";


const useGetConversations = () => {
    const [loading, setLoading] = useState(false);
    const [conversations, setConversations] = useState([]);

    useEffect(() => {
        const getConversations = async () => {
            setLoading(true);
            try {
                const res = await fetch("/api/users");
                const data = await res.json();
                if (data.error) {
                    throw new Error(data.error);
                }
                
                setConversations(data);
                
            } catch (error) {
                toast.error(error.message);
            } finally {
                setLoading(false);
                
            }
        };

        getConversations();
    }, []);
    console.log("before return statement",conversations[0]);
    console.log("before return statement",conversations[0]?.name);
    return { loading, conversations };
    
};
export default useGetConversations;
Sudip Shrestha
2024-02-26

最好对组件进行条件渲染。如果钩子 useGetConversations 检索到空值,则使用该钩子的组件将执行如下操作:

if (conversations.length === 0) {
  return <Fallback />
}

回退是某种辅助组件,就像加载一样。我认为可选链式操作没问题,但我不建议每次都使用它。处理复杂对象时,代码会变得非常混乱。

sainzcr
2024-02-26