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

React+TypeScript项目中解决TS(18048) 'result可能为undefined'错误

解决React+TypeScript中TS(18048)错误及相关问题

1. 消除'result可能为undefined'报错

你的result状态没有初始值,TypeScript推断它的类型是Movie[] | undefined,调用map时自然会报错。给useState设置空数组作为默认值即可:

const [result, setResult] = useState<Movie[]>([]);

2. 修正API返回数据的处理逻辑

API返回的是电影数组,你直接修改movies.releaseDate是错误的——数组本身没有这个属性,要遍历每个电影单独处理日期:

async function LoadMovies() {
  try {
    const response = await fetch("https://localhost:****/api/movies");
    if (!response.ok) throw new Error(`请求失败,状态码: ${response.status}`);
    const movies: Movie[] = await response.json();
    // 遍历处理每个电影的日期字段
    const processedMovies = movies.map(movie => {
      if (movie.releaseDate) {
        movie.releaseDate = ConvertDate(new Date(movie.releaseDate));
      }
      return movie;
    });
    setResult(processedMovies);
  } catch (err) {
    console.error("加载电影数据出错:", err);
  }
}

另外加了try/catch处理请求失败的情况,避免程序崩溃。

3. 修复日期转换函数的低级错误

getFullYear、getMonth、getDate是Date对象的方法,必须加()调用,否则你拿到的是函数本身,不是日期数值:

function ConvertDate(d: Date) {
  return (
    d.getFullYear() +
    ("0" + (d.getMonth() + 1)).slice(-2) + // 月份从0开始,要加1才是实际月份
    ("0" + d.getDate()).slice(-2)
  );
}

4. 优化Movie类型定义

用interface替代class更适合JSON数据场景——API返回的是普通对象,不需要类实例:

// Movies.ts
export interface Movie {
  title?: string;
  director?: string;
  genre?: string;
  price?: number;
  revenue?: number;
  releaseDate?: string;
}

如果坚持用class,要么确保实例化时所有属性都赋值,要么渲染时用可选链(movie.title?.trim())或空值合并运算符(movie.title ?? "未知")处理undefined的情况,避免渲染报错。

5. 补充React列表的key属性

React渲染列表时要求每个元素有唯一key,否则会触发警告,直接用数组索引(如果没有更唯一的标识的话):

function ProcessMovie(movie: Movie, index: number) {
  return (
    <tr key={index}>
      <td>{movie.title ?? "未设置"}</td>
      <td>{movie.genre ?? "未设置"}</td>
      <td>{movie.director ?? "未设置"}</td>
      <td>{movie.price ?? 0}</td>
      <td>{movie.revenue ?? 0}</td>
      <td>{movie.releaseDate ?? "未设置"}</td>
    </tr>
  );
}

这里用了??空值合并运算符,当属性为undefined时显示默认值,提升用户体验。


完整修正后的代码

// MoviesList.tsx
import { useEffect, useState } from "react";
import { Movie } from "./Movies";

export default function MoviesList() {
  const [result, setResult] = useState<Movie[]>([]);

  useEffect(() => {
    LoadMovies();
  }, []);

  async function LoadMovies() {
    try {
      const response = await fetch("https://localhost:****/api/movies");
      if (!response.ok) throw new Error(`HTTP错误: ${response.status}`);
      const movies: Movie[] = await response.json();
      const processedMovies = movies.map(movie => {
        if (movie.releaseDate) {
          movie.releaseDate = ConvertDate(new Date(movie.releaseDate));
        }
        return movie;
      });
      setResult(processedMovies);
    } catch (error) {
      console.error("加载电影失败:", error);
    }
  }

  function ProcessMovie(movie: Movie, index: number) {
    return (
      <tr key={index}>
        <td>{movie.title ?? "未设置"}</td>
        <td>{movie.genre ?? "未设置"}</td>
        <td>{movie.director ?? "未设置"}</td>
        <td>{movie.price ?? 0}</td>
        <td>{movie.revenue ?? 0}</td>
        <td>{movie.releaseDate ?? "未设置"}</td>
      </tr>
    );
  }

  function ConvertDate(d: Date) {
    return (
      d.getFullYear() +
      ("0" + (d.getMonth() + 1)).slice(-2) +
      ("0" + d.getDate()).slice(-2)
    );
  }

  return (
    <table>
      <tbody>{result.map(ProcessMovie)}</tbody>
    </table>
  );
}
// Movies.ts
export interface Movie {
  title?: string;
  director?: string;
  genre?: string;
  price?: number;
  revenue?: number;
  releaseDate?: string;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 09:56:10