React组件中无法为props对象添加新属性的问题排查
问题与解决方案
问题描述
向子组件传递包含对象的props,希望在子组件中基于props初始化state,同时给props内的每个对象添加额外属性后再完成初始化。逻辑写在useEffect中,但遇到两个问题:
- 处理完props后打印变量,看不到添加属性后的结果
- 直接在
console.log里调用map添加属性,却能显示正确结果
父组件代码
import EditParts from "./EditPartsChange"; function MechanicTable() { const [partsList, setpartsList] = useState([ {id:123,name:"oil filter"}, {id:124,name:"air filter"} ]); return( <> <EditParts partsList={partsList} /> </> ); } export default MechanicTable;
子组件原代码
function EditParts({ partsList }) { const [_partsList, setPartsList] = useState([]); useEffect(() => { let parts = [...partsList]; parts = parts.map((part) => ({ ...part, dbvalue: "db value", })); // 循环后打印parts变量无法显示更新结果 // 此处能显示正确结果👇 console.log( parts.map((part) => ({ ...part, dbvalue: "db value", })) ); // 此处能显示正确结果☝️ const unSubscribe = setPartsList(parts); return () => {unSubscribe;}; }, [partsList]); return(<></>); } export default EditParts;
问题分析与解决
1. 控制台显示问题
你看到的“打印parts变量看不到更新结果”是浏览器控制台的引用类型延迟更新特性导致的:当你打印数组、对象这类引用类型时,控制台显示的是该引用的当前值(你展开查看时的值),而非你执行console.log时刻的快照。
解决方法:用JSON.stringify把处理后的数组转成字符串打印,就能看到执行打印时的真实结果:
console.log(JSON.stringify(parts));
2. 冗余代码与逻辑优化
setPartsList是React的状态更新函数,没有返回值,所以const unSubscribe = setPartsList(parts);完全是冗余代码,清理函数里的unSubscribe;也没有任何作用,直接删除即可。- 如果
partsList不会动态变化,你可以直接在useState初始化时处理props,不需要useEffect:
const [_partsList, setPartsList] = useState( partsList.map(part => ({...part, dbvalue: "db value"})) );
- 如果
partsList会动态变化,需要监听props更新状态,修正后的useEffect如下:
修正后的子组件代码
function EditParts({ partsList }) { const [_partsList, setPartsList] = useState([]); useEffect(() => { // 处理props,为每个对象添加dbvalue属性 const processedParts = partsList.map(part => ({ ...part, dbvalue: "db value" })); // 打印快照,查看真实处理结果 console.log("处理后的parts:", JSON.stringify(processedParts)); // 更新状态 setPartsList(processedParts); }, [partsList]); return <></>; } export default EditParts;
内容的提问来源于stack exchange,提问作者Usama Abdul Razzaq
相关产品推荐
相关产品推荐

