Next.js TypeScript中useState使用报错,求电影列表过滤优化方案
问题解决:先处理报错
default是JavaScript的保留关键字,不能用来命名变量/状态,把default改成allMovies这类合法名称就能解决截图中的报错。
现有代码基础问题修复
修正TypeScript类型定义
你把datas定义为string[],但接口返回的是电影对象数组,先定义Movie类型并修正状态:interface Movie { id: number; title: string; age_rating: number; // 补充接口返回的其他字段 } const [datas, setData] = useState<Movie[]>([]); const [allMovies, setAllMovies] = useState<Movie[]>([]);移除冗余异步标识
getCategory内部没有异步操作,删掉async关键字。统一异步代码风格+错误处理
避免async/await和.then混用,同时添加请求失败的捕获逻辑:useEffect(() => { const fetchData = async () => { setLoading(true); try { const res = await fetch("https://seleksi-sea-2023.vercel.app/api/movies"); if (!res.ok) throw new Error("请求失败"); const data = await res.json(); setData(data); setAllMovies(data); } catch (err) { console.error("获取电影数据失败:", err); } finally { setLoading(false); } }; fetchData(); }, []);
更优的筛选实现思路
不要直接修改展示数据,改用存储筛选条件+计算展示数据的模式,扩展性更强:
// 新增筛选条件状态 const [filterType, setFilterType] = useState<string | null>(null); // 用useMemo缓存筛选结果,避免重复计算 const filteredMovies = useMemo(() => { if (!filterType) return allMovies; if (filterType === 'Kids') { return allMovies.filter(movie => movie.age_rating <= 12); } if (filterType === 'Adults') { return allMovies.filter(movie => movie.age_rating > 12); } return allMovies; }, [allMovies, filterType]); // 筛选函数简化为设置条件 const getCategory = (t: string) => { setFilterType(t); }; // 新增重置筛选功能 const resetFilter = () => { setFilterType(null); };
这种模式的优势:
- 保留原始数据纯净性,无需依赖原始状态反复拷贝
- 扩展新筛选条件(如年份、评分)只需修改筛选条件和逻辑
- useMemo缓存结果,减少不必要的数组计算和组件重渲染
细节优化建议
- 把
datas改名为displayMovies,语义更清晰 - 加载状态配合条件渲染,比如加载时显示loading组件、错误时显示提示
- 用枚举替代魔法字符串,避免拼写错误:
enum FilterType { Kids = 'Kids', Adults = 'Adults', All = 'All' }
内容的提问来源于stack exchange,提问作者fyz 08
相关产品推荐
相关产品推荐

