Javascript Reactjs:TypeError:无法读取属性';地图';未定义的

Javascript Reactjs:TypeError:无法读取属性';地图';未定义的,javascript,node.js,reactjs,Javascript,Node.js,Reactjs,我一直在做React项目,我一直在使用axios从后端获取数据。我多次收到(TypeError:cannotreadproperty'map'of undefined)错误,我尝试了多次修复,但没有希望修复。我添加了一个用于加载的钩子,以确保在呈现之前数据是存在的,但是如果我返回到第四个页面之间,我会收到相同的错误 这是我的密码: function Developer(props) { const [data, setData] = useState(); const [load

我一直在做React项目,我一直在使用axios从后端获取数据。我多次收到(TypeError:cannotreadproperty'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> 
        )}
功能开发人员(道具){
const[data,setData]=useState();
常量[loading,setLoading]=useState(true)
const[error,setError]=useState();
var id=props.match.params.id
变量位置=props.match.params.location
useffect(()=>{
axios(`http://localhost:5000/api/${location}/${id}`)
。然后((响应)=>{
setData(response.data);
})
.catch((错误)=>{
console.error(“获取数据时出错:”,错误);
设置错误(错误);
})
.最后(()=>{
设置加载(假);
});
}, []);
如果(加载)返回“加载…”;
if(error)返回“error!”;
返回(
{data.Developer}
    { data.Projects.map((project)=>(
  • )) }
)}
在绘制数据属性地图之前,您应该先检查数据属性的性质

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

    我建议您使用javascrip fetch

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

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

    这里有一个简单的解决方案

    {data ? data.Projects.map((project) => (<li key={project._id}>
                        <a href={`/${location}/${id}/${project._id}`}>{project.Project}</a></li>)) :<div>Loading..</div>}
    
    {data?data.Projects.map((project)=>(
  • ):正在加载..}
    所以我在这里做的是使用一个三元运算符,它要做的是检查数据状态是否有数据,如果有,它将以另一种方式显示数据,它将显示“加载…”


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

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

    尝试打印出返回的数据

            axios(`http://localhost:5000/api/${location}/${id}`)
            .then((response) => {
              console.log(response.data);
              setData(response.data);
            })
    
    它可能是有效的响应,但不包含该变量
    data.Projects
    。如果要处理缺少该值的情况,可以使用以下方法:

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

    这样,如果
    data.Projects
    为falsy,它将被一个空数组替换,并将调用
    [].map(…)
    如前所述,您的设置加载(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> 
            )}
    
    功能开发人员(道具){
    const[data,setData]=useState();
    常量[loading,setLoading]=useState(true)
    const[error,setError]=useState();
    var id=props.match.params.id
    变量位置=props.match.params.location
    useffect(()=>{
    //哦,看,我们现在处于加载状态,因为此时数据还没有从服务器返回。
    设置加载(真);
    axios(`http://localhost:5000/api/${location}/${id}`)
    。然后((响应)=>{
    setData(response.data);
    //棒极了,数据已经从服务器返回,我们不再加载了,但是finally块为我们处理了这个场景。
    })
    .catch((错误)=>{
    console.error(“获取数据时出错:”,错误);
    设置错误(错误);
    })
    .最后(()=>{
    设置加载(假);
    });
    }, []);
    如果(加载)返回“加载…”;
    if(error)返回“error!”;
    返回(
    {data.Developer}
    
      { data&&data.Projects.length&&data.Projects.map((项目)=>(
    • )) }
    )}
    data.Projects未定义。我们能看到api调用的响应是什么样子吗?此外,在api调用之前,您似乎没有将加载变量设置为true。因此,您可能需要检查jsx中的数据是否未定义。基本上,看起来正在发生的事情是,您正在尝试循环一个未定义的变量,但是您没有告诉视图等待数据被获取。加载变量将在axios调用之前为您设置加载(true)。然后,在setData.data.Projects之前,setLoading(false)是axios调用返回的集合的一部分,因此它存在。我真的不知道什么时候把加载变量设置为true,什么时候设置为false。请您解释一下,可能定义了
    数据
    ,但没有定义
    数据.项目
    ,您的解决方案会告诉用户,它仍在加载,但已完成,数据丢失。这可能会产生误导。如果
    data.Projects
    不是数组,则仍会出现错误。这是因为Projects不是数组。您可以创建data.Projects日志以查看项目类型<代码>控制台.日志(数据.项目)