【问题标题】:React: Accessing an objects properties within an array that I have mapped反应:访问我已映射的数组中的对象属性
【发布时间】:2021-12-25 06:32:12
【问题描述】:

我正在尝试制作我的第一个真正的 React 应用程序并从数据库中提取信息,更新状态以将该信息设置为数组,然后尝试访问数组中对象的属性。

function App() {

  const [students, setStudents] = useState([]);

  function fetchStudentInfo() {
    fetch('https://api.hatchways.io/assessment/students')
      .then(response => {
        return response.json();
      })
      .then(data => {
        const transformedStudentData = data.students.map(studentData => {
          return {
            imgURL: studentData.pic,
            fullName: `${studentData.firstName} ${studentData.lastName}`,
            email: studentData.email,
            company: studentData.company,
            skill: studentData.skill
          }
        });
        setStudents(transformedStudentData);
      });
  }

  fetchStudentInfo();

  return (
    <div> {console.log(students[0].fullName)}
      <h1>Student Assessments</h1>
    </div>
  )

}

export default App;

我知道我不应该控制台。记录我想要获取的信息,但我什至不确定如何在 React 中使用控制台来了解如何访问我的变量。无论如何,我得到“TypeError:无法读取未定义的属性(读取'fullName')”作为错误并且它失败了。 我真的想将数组作为要在我的组件中使用的属性传递下去,但我已经取出代码来尝试为自己简化问题,这就是我碰壁的地方。

【问题讨论】:

    标签: javascript arrays reactjs dictionary object


    【解决方案1】:

    在第一次渲染时,您的 students 状态是一个空数组,因为这就是您初始化它的方式。在第一次渲染时,您无法访问第一个索引(因为尚未获取数据或状态已更新),并且您无法访问尚不存在的元素的属性。

    所以你需要一个条件来呈现:1)如果students.length 为零返回加载消息(例如)2)否则map 在你现在知道存在的学生数组上生成学生列表名字。

    这是一个工作示例,它使用useEffect 在模拟 API fetch 的三秒后将数组添加到状态。您应该像这样将useEffect 用于您的fetch(带有一个空的依赖数组),而不是直接在组件中调用您的函数。

    const { useEffect, useState } = React;
    
    const json = '[{ "fullName": "Bob" },{ "fullName": "Karen" },{ "fullName": "Rick" }]';
    
    function mockApi() {
      return new Promise((res, rej) => {
        setTimeout(() => res(json), 3000);
      });
    }
    
    function Example({ data }) {
    
      const [ students, setStudents ] = useState([]);
      
      useEffect(() => {
        function getData() {
          mockApi()
            .then(json => JSON.parse(json))
            .then(data => setStudents(data));
        }
        getData();
      }, []);
    
      // Initial log will be `[]`
      // Second log will be the updated state stringified
      useEffect(() => {
        console.log(JSON.stringify(students));
      }, [students]);
    
      // No data, so return the loading message, or spinner
      if (!students.length) return <div>Loading: wait 3 seconds</div>
    
      // Data! `map` over it to produce the list
      return (
        <ul>
          {students.map(student => {
            return <li>{student.fullName}</li>;
          })}
        </ul>
      );
    
    };
    
    ReactDOM.render(
      <Example />,
      document.getElementById('react')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <div id="react"></div>

    【讨论】:

    • 我想我应该了解更多关于useEffect的知识...谢谢,这很简单地解决了我的问题。
    • 没问题。 useEffect 基本上是在寻找状态的变化。如果你传入一个空的依赖数组,它将在组件挂载时运行一次。如果您将状态传递给该数组,则每次更新该状态时都会运行效果。
    • 我在我的回答中添加了一个额外的效果,向您展示我的意思。当students 更新时,效果会处理更新并打印出状态的 JSON。 @HarrySIV
    猜你喜欢
    • 2021-02-09
    • 1970-01-01
    • 2019-01-07
    • 2017-03-16
    • 2020-07-29
    • 2020-10-31
    • 2021-11-09
    • 1970-01-01
    • 2015-08-03
    相关资源
    最近更新 更多