You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中打印对象字段存在,但访问属性返回undefined的原因?

问题描述

我有一个幸存者列表:

const survivorsList = [
  {
    id: 1,
    name: "Ace Visconti",
    image_path: "static/survivors/ace_visconti.jpg",
  },
  {
    id: 2,
    name: "Vittorio Toscano",
    image_path: "static/survivors/vittorio_toscano.jpg",
  },
  {
    id: 3,
    name: "Nancy Wheeler",
    image_path: "static/survivors/nancy_wheeler.jpg",
  },
  {
    id: 4,
    name: "Claudette Morel",
    image_path: "static/survivors/claudette_morel.jpg",
  },
];

在React应用的渲染函数中尝试访问该列表:

renderSurvivorName = () => {

  const randomSurvivor = this.state.survivorsList.filter(
      (survivor) => survivor.name === "Ace Visconti"
  );

  console.log("Random Survivor: " + JSON.stringify(randomSurvivor))
  console.log("Survivor Name: " + randomSurvivor.name);

  // return randomSurvivor['name'];
  return randomSurvivor.name;
};

控制台输出如下:

Random Survivor: [{"id":1,"name":"AceVisconti","image_path":"static/survivors/ace_visconti.jpg"}]. App.js:62
Survivor Name: undefined. App.js:63

我尝试过点语法和方括号语法访问属性,均返回undefined。怀疑是两次调用间作用域变化或页面重载导致值未设置?查阅过StackOverflow文章,但因未进行API调用,认为无需使用async,这个想法是否错误?

完整React代码

import React, { Component } from "react";

const survivorsList = [
  {
    id: 1,
    name: "Ace Visconti",
    image_path: "static/survivors/ace_visconti.jpg",
  },
  {
    id: 2,
    name: "Vittorio Toscano",
    image_path: "static/survivors/vittorio_toscano.jpg",
  },
  {
    id: 3,
    name: "Nancy Wheeler",
    image_path: "static/survivors/nancy_wheeler.jpg",
  },
  {
    id: 4,
    name: "Claudette Morel",
    image_path: "static/survivors/claudette_morel.jpg",
  },
];

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      survivorsList: survivorsList,
      survivorName: "Ace Visconti"
    };
  }

  // displayRandom = (status) => {
  //   if (status) {
  //     return this.setState({ randomCalculated: true });
  //   }
  //
  //   return this.setState({ randomCalculated: false });
  // };

  renderSurvivorTitle = () => {
    return (
        <div className="nav nav-tabs">
        <span
            className={this.state.randomCalculated ? "nav-link active" : "nav-link"}
            onClick={() => this.displayRandom(true)}
        >
          Survivor
        </span>
        </div>
    );
  };

  renderSurvivorName = () => {

    const randomSurvivor = this.state.survivorsList.filter(
        (survivor) => survivor.name === "Ace Visconti"
    );

    console.log("Random Survivor: " + JSON.stringify(randomSurvivor))
    console.log("Survivor Name: " + randomSurvivor.name);

    // return randomSurvivor['name'];
    return <div>Survivor: {this.state.survivorName}</div>;
  };

  render() {
    return (
        <main className="container">
          <h1 className="text-white text-uppercase text-center my-4">Todo app</h1>
          <div className="row">
            <div className="col-md-6 col-sm-10 mx-auto p-0">
              <div className="card p-3">
                <div className="mb-4">
                  <button
                      className="btn btn-primary"
                  >
                    Select Random Survivor
                  </button>
                </div>
                <div>{this.renderSurvivorTitle()}</div>
                <div>{this.renderSurvivorName()}</div>
                {/*<div>{"Ace Visconti"}</div>*/}
              </div>
            </div>
          </div>
        </main>
    );
  }
}

export default App;

package.json

{
  "name": "dbd-randomizer-ui",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "latest",
    "@testing-library/react": "latest",
    "@testing-library/user-event": "latest",
    "react": "latest",
    "react-dom": "latest",
    "react-scripts": "latest",
    "web-vitals": "latest",
    "bootstrap": "latest",
    "reactstrap": "latest"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

问题原因与解决方法

核心问题

你使用的filter方法返回的是符合条件的元素组成的数组,而非单个对象。所以randomSurvivor是一个数组,数组本身没有name属性,自然返回undefined。从控制台输出也能看出结果被包裹在数组中:Random Survivor: [{"id":1,...}]。

解决步骤

  1. 替换filter为find:如果要查找单个匹配元素,使用find方法,它会返回第一个符合条件的对象,而非数组:
const randomSurvivor = this.state.survivorsList.find(
  (survivor) => survivor.name === "Ace Visconti"
);
  1. 处理空值情况:如果没有找到匹配元素,find会返回undefined,访问属性前建议做判断避免报错:
console.log("Survivor Name: " + (randomSurvivor?.name || "未找到幸存者"));
return <div>Survivor: {randomSurvivor?.name || "未找到幸存者"}</div>;
  1. 关于async的疑问:你的判断正确,这里没有异步操作(如API请求),完全不需要使用async/await,问题与异步无关。

额外修复点

  • 当前renderSurvivorName最终返回的是this.state.survivorName,和查找逻辑无关,若要显示查找结果,需改为返回randomSurvivor?.name。
  • renderSurvivorTitle中用到了this.state.randomCalculated,但state未初始化该值,会导致报错,建议在constructor中补充:
this.state = {
  survivorsList: survivorsList,
  survivorName: "Ace Visconti",
  randomCalculated: false // 初始化状态
};

同时取消displayRandom方法的注释,否则点击事件会报错。

内容的提问来源于stack exchange,提问作者CryptoRAT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:16:14