React中planState.map is not a function报错问题排查
问题分析与解决:
planState.map is not a function 错误 错误原因
代码里planState初始被声明为数组:
const [planState, setPlanState] = useState([]);
但plan函数通过展开语法把它转换成了对象:
function plan(name, value) { setPlanState(prev => ({...prev, [name]: value})) };
当数组被展开到对象中时,数组索引会变成对象的键,最终planState的类型从数组变成了普通对象。而map是数组专属方法,对象没有这个方法,因此调用planState?.map时触发错误。
修复方案
从代码的使用场景(通过键名x、d访问值)来看,planState更适合作为对象存储,调整步骤如下:
1. 修正初始状态
把planState的初始值从数组改为空对象:
const [planState, setPlanState] = useState({});
2. 调整渲染逻辑
因为planState是对象,不能直接用map,可以直接访问目标键对应的值进行处理(更贴合代码原有意图):
<div> {planState.d?.split(";")?.map(plan => ( plan && <div key={plan}> <input type="radio" value={plan} checked={selectThisPlanState === plan} onChange={() => changeID(plan)} />{plan} </div> ))} </div>
额外优化点
plan(["d"], protectionPlan)中的["d"]可以直接写成字符串"d",数组会被自动转为字符串键名,没必要传数组。- 拼接字符串时改用数组
push后join的方式,避免频繁字符串拼接的性能损耗:
const protectionPlans = []; AddOns.forEach(protectionPlan_from_db => { if (productId === protectionPlan_from_db.productId) { protectionPlans.push(protectionPlan_from_db.add_On); } }); const protectionPlan = protectionPlans.join(";");
修改后的完整代码
import { useState, useEffect } from "react"; import AddOns from "./helpers/AddOns.js"; import { variables } from './helpers/Variables.js'; function App() { const [selectThisPlanState, setSelectThisPlanState] = useState({}); function changeID(new_id) { setSelectThisPlanState(new_id); alert(new_id); } // 初始值改为空对象 const [planState, setPlanState] = useState({}); function plan(name, value) { setPlanState(prev => ({...prev, [name]: value})) }; const getComputerProtectionPlansFromDb = async (productId) => { const protectionPlans = []; const URL = `${variables.API_URL_ADDONS}/${productId}`; const response = await fetch(URL); const addOns = await response.json(); addOns.forEach(protectionPlan_from_db => { if (productId === protectionPlan_from_db.productId) { protectionPlans.push(protectionPlan_from_db.add_On); } }); // 直接传字符串键名 plan("d", protectionPlans.join(";")); } useEffect(() => { getComputerProtectionPlansFromDb(1); plan("x", "yyy"); }, []); return ( <> <div> {planState["x"]} <br /> {/* print "yyy" */} </div> <div> {/* 直接处理planState.d的值 */} {planState.d?.split(";")?.map(plan => ( plan && <div key={plan}> <input type="radio" value={plan} checked={selectThisPlanState === plan} onChange={() => changeID(plan)} />{plan} </div> ))} </div> </> ) } export default App;
内容的提问来源于stack exchange,提问作者Cookie
相关产品推荐
相关产品推荐

