React函数组件传递数组Props至子组件返回undefined问题排查
我正在使用React函数组件开发作品集页面,想要创建一个展示所用技术的组件,组件结构为Skills容器→前端技能、设计技能等子组件→Skill项。我在外部js文件中定义了技术栈数组,希望在主Skill容器中导入后传递给对应子组件,但传递的数组Props返回undefined。直接在子组件中导入该数组可正常显示数据,但我希望实现组件复用,不想为每个技能类别单独创建组件。
相关代码如下:
技能数据js文件
export const stackToolsFE = [{ tool_Name: 'React', tool_Img: 'https://cdn-icons-png.flaticon.com/512/1126/1126012.png' }, { tool_Name: 'JavaScript', tool_Img: 'https://cdn-icons-png.flaticon.com/512/5968/5968292.png' },];
单个Skill项组件
const StackTool = (props) => { return ( <div className="stackToolContainer"> <StackIcon toolName={props.tool.tool_Name} toolImgSrc={props.tool.tool_Img}/> <Text content={props.tool.tool_Name} /> </div> ) }
技能类别容器组件
const TechStackTools = (props) => { return ( <> <TextCentered variant={'s'} content={ props.toolsCategory } /> <div className="toolsWrapper"> {props.toolsList.map(tool => <StackTool tool={tool} />)} </div> </> ) }
主容器组件
import { stackToolsFE } from '../../../datafiles/stack' const TechStackSection = props => { const stackToolsFrontEnd = stackToolsFE; return ( <div className="techStackContainer"> <div className="techStackTitles"> <SectionHeader sectionTitle={'Skills'}/> <SectionSubheader sectionSubTitle={'Technology tools I use'} /> </div> <div className="techStackToolsWrapper"> <TechStackTools toolsCategory={'Frontend'} toolsList={stackToolsFrontEnd} /> <TechStackTools toolsCategory={'Design'}/> <TechStackTools toolsCategory={'Other'}/> </div> </div> ) }
如上述代码所示,我在主组件中导入数据并赋值给新常量后传递,仍未解决问题。请问问题出在哪里?
核心问题
你渲染TechStackTools组件时,Design和Other这两个实例没有传入toolsList props,当组件尝试调用props.toolsList.map()时,props.toolsList是undefined,直接调用map方法会触发报错,进而可能影响整个组件渲染,让你误以为传递给Frontend的props也出了问题。
另外,即使是Frontend的情况,也建议增加空值判断,避免后续数据异常时出现相同问题。
解决步骤
为所有
TechStackTools实例传入对应的数据数组
先在数据文件中补充Design和Other类别的数据:// 数据文件中新增 export const stackToolsDesign = [ { tool_Name: 'Figma', tool_Img: '对应图标地址' }, // 其他设计工具 ]; export const stackToolsOther = [ { tool_Name: 'Git', tool_Img: '对应图标地址' }, // 其他工具 ];然后在主组件中导入并传递:
import { stackToolsFE, stackToolsDesign, stackToolsOther } from '../../../datafiles/stack' const TechStackSection = props => { return ( <div className="techStackContainer"> {/* ... 其他代码 ... */} <div className="techStackToolsWrapper"> <TechStackTools toolsCategory={'Frontend'} toolsList={stackToolsFE} /> <TechStackTools toolsCategory={'Design'} toolsList={stackToolsDesign}/> <TechStackTools toolsCategory={'Other'} toolsList={stackToolsOther}/> </div> </div> ) }在
TechStackTools组件中增加空值保护
即使某个类别暂时没有工具,也避免组件崩溃:const TechStackTools = (props) => { // 先判断toolsList是否存在且为数组 const tools = props.toolsList || []; return ( <> <TextCentered variant={'s'} content={ props.toolsCategory } /> <div className="toolsWrapper"> {tools.map(tool => <StackTool key={tool.tool_Name} tool={tool} />)} </div> </> ) }同时给
map返回的StackTool组件加上key属性,符合React列表渲染规范,避免控制台警告。可选:优化数据结构
可以把所有技能类别数据整合为一个数组,减少主组件中的重复代码:// 数据文件中 export const skillCategories = [ { category: 'Frontend', tools: [ { tool_Name: 'React', tool_Img: '对应地址' }, { tool_Name: 'JavaScript', tool_Img: '对应地址' } ] }, { category: 'Design', tools: [/* 设计工具 */] }, { category: 'Other', tools: [/* 其他工具 */] } ];主组件中直接遍历渲染:
import { skillCategories } from '../../../datafiles/stack' const TechStackSection = props => { return ( <div className="techStackContainer"> {/* ... 其他代码 ... */} <div className="techStackToolsWrapper"> {skillCategories.map(category => ( <TechStackTools key={category.category} toolsCategory={category.category} toolsList={category.tools} /> ))} </div> </div> ) }
内容的提问来源于stack exchange,提问作者curiousRedReptile

