React中map函数内渲染多组件:嵌套map与组件调用故障排查
解决React map函数内渲染多个组件的问题
你在处理带标点的单词拆分并渲染对应组件时遇到了组件不显示的问题,我帮你梳理下代码里的几个关键问题,然后给出修复方案:
问题分析
你的代码里主要有这几个导致组件不渲染的原因:
switch方法没有返回生成的JSX元素,render方法拿不到要渲染的内容- 嵌套map循环中,
freshItem和puncItem会被每次循环覆盖,最后只保留最后一次循环的结果 - 使用未声明的
self(缺少const/let),会导致全局变量污染,上下文指向错误 callComp里的setState完全没必要,反而会触发额外重渲染,而且你并没有用这个状态来渲染组件- 直接在render里调用
switch方法,会导致每次渲染都执行一遍逻辑,不符合React的渲染逻辑
修复方案
我们可以把拆分逻辑和组件渲染逻辑整理清楚,直接在render里(或者单独的方法里)返回要渲染的组件数组:
修正后的完整代码
<div id="container"></div> <script type="text/babel"> class A extends React.Component { constructor(props){ super(props); this.state={} } render(){ return ( <div> {this.props.item}hello </div> ) } } class B extends React.Component { constructor(props){ super(props); } render(){ return( <div> {this.props.items} </div> ) } } class C extends React.Component { constructor(props){ super(props); this.state = { cstate:true, } } // 单独处理单个单词的拆分和组件生成 processItem(item) { const punctuations = [';',':','<']; // 检查单词是否包含任何标点 const foundPunc = punctuations.find(punc => item.includes(punc)); if (foundPunc) { const splitIndex = item.indexOf(foundPunc); const freshItem = item.substr(0, splitIndex); const puncItem = item.substr(splitIndex); // 返回两个组件:单词部分和标点部分 return [ <A key={`word-${item}-${freshItem}`} item={freshItem}/>, <B key={`punc-${item}-${puncItem}`} items={puncItem}/> ]; } else { // 没有标点,只返回A组件 return <A key={`word-${item}`} item={item}/>; } } render(){ if (!this.state.cstate) return null; const items = ['a;','as','df','fg']; // 处理所有item,收集所有要渲染的组件 const renderedComponents = items.flatMap(item => this.processItem(item)); return( <div>{renderedComponents}</div> ) } } ReactDOM.render(<C/>,document.getElementById("container")); </script> </div>
关键修改点说明
- 新增
processItem方法,专门处理单个单词的拆分和组件生成,逻辑更清晰 - 使用
find代替嵌套map,直接找到单词里的第一个标点(如果有的话),避免重复覆盖变量 - 使用
flatMap来处理每个item返回的组件数组,把二维数组转成一维,方便React渲染 - 给每个组件添加唯一的
key属性,这是React列表渲染的要求,避免警告和渲染异常 - 移除了不必要的
setState和switch方法,直接在render里处理渲染逻辑(如果逻辑复杂,也可以把拆分后的数据存到state里,但这里逻辑简单,直接处理更高效) - 修复了
self未声明的问题,现在不需要额外绑定上下文,类方法的上下文已经正确
这样修改后,组件A和B就能正常渲染了:每个带标点的单词会拆分成A(单词部分)和B(标点部分),不带标点的单词只渲染A组件。
内容的提问来源于stack exchange,提问作者stackoverhelp
相关产品推荐
相关产品推荐

