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
相关产品推荐
相关产品推荐

