【问题标题】:Understanding useEffect behaviour了解 useEffect 行为
【发布时间】:2020-09-08 19:53:33
【问题描述】:

我有一个名为 StudentPage 的组件,它根据当前登录的学生 currentStudent 显示学生的详细信息。 currentStudent 对象不包含 Student 模型的所有属性,因此我使用 axios 请求获取所有 students 并通过 id 获取与 curresntStudent 匹配的 student,并获取我的所有属性需要它。

现在的问题是,当我尝试访问 student 属性的值时,我收到错误“TypeError: Cannot read property 'name' of undefined”。 所以我 console.log-studentscurrentStudentstudent 并注意到当我尝试访问 currentStudent.name在下面评论)时, console.log-students 输出我数据库中的学生列表,还注意到 console.log-student 对象的输出与 currentStudent 的输出匹配.但是,当我尝试访问 student.name下面的代码)时,console.log 输出显示学生列表的空数组导致 student 对象为未定义。

谁能帮忙解释一下为什么我会注意到这种行为,也许是一些我还不理解的 useEffect 概念。

const StudentPage=({currentStudent, students, fetchStudents})=>{

useEffect(()=>{
        fetchStudents();
    },[]) //I tried making currentStudent a dependency [currentStudent] but same behaviour ocurs.

console.log(students);
console.log(currentStudent)

const student= students.filter(pupil=>{return(pupil.id===currentStudent.id)})[0]
console.log(student)

// return (<div>name: {currentStudent.name}</div>) this works normally but currentUser doesn't have all attributes i need
return(
<div>Name: {student.name}</div>                                     
)

const mapStateToProps= state=>{
return {
        students: state.students
       }
 }

export default(mapStateToProps,{fetchStudents})(StudentPage);

【问题讨论】:

  • 您正在尝试过滤在安装组件之前未定义的数组。尝试将您的 student 变量声明为状态并在获取 students 后填充您的状态
  • student 在初始渲染时不可用,因为它是异步检索的。这与 useEffect 无关,而是与 JS 的工作方式有关。如果学生在 useEffect() 之前是空数组,则在 student=students... 行没有机会变成全数组。学生可以===undefined,布局需要根据这个事实使用条件
  • const [学生,setStudent] = useState(null);当您调用 API 时,请使用 async-await const students = fetchStudents(); setStudent(students.filter(pupil=>{return(pupil.id===currentStudent.id)})[0]) 然后在 return {student ?
    姓名:{student.name}
    }
  • 另外,在使用钩子时你真的需要 (mapStateToProps,mapDispatchToprops) 吗?我不这么认为。
  • 此外,这里明显的问题是您不应该出于调试目的而信任控制台输出,因为它输出对对象的引用并且不反映其实时状态。如果你想看到后者,请使用console.log(JSON.stringify(students))

标签: javascript reactjs


【解决方案1】:

Here you can find an example on how to do what you want:

import React from "react";
import { useState, useEffect } from "react";

export function StudentPage({ studentId, fetchStudents }) {
  const [student, setStudent] = useState();

  useEffect(() => {
    (async () => {
      const students = await fetchStudents();
      const currentStudent = students.find((student) => {
        console.log(student);
        return student.id === studentId;
      });
      setStudent(currentStudent);
    })();
  }, [studentId, fetchStudents]);

  return (
    <>
      Student ID: {studentId}, Student name: {student && student.name}
    </>
  );
}

useEffect 将在依赖项(在本例中为studentId)发生变化时触发,包括在第一次渲染时。您应该将值存储在状态中(使用useState)并进行必要的检查以查看它是否为空。

【讨论】:

  • 我正在使用 redux 来管理我的状态(currentStudent 和 students 都是从 redux 商店获得的)。我解决了我的问题,只需添加此行{student &amp;&amp; student.name} 以检查学生是否为空。添加上面的代码行是我对代码所做的唯一更改。我的方法有什么问题吗?
  • 不,没关系,使用{ student &amp;&amp; student.name }是一种常见的方法,如果您打算引用很多值并且不想这样做,您也可以使用get function from lodash{ _.get(student, 'name') } student &amp;&amp; 每次检查。
猜你喜欢
  • 2020-06-22
  • 2021-11-12
  • 2021-04-02
  • 2016-09-28
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多