React渲染组件数组时的key添加问题求助
解决React组件数组渲染时的Key问题(保留数组写法)
嘿,我完全理解你想要保留这种对新手友好的组件数组写法,同时搞定key的问题——咱们一步步来解决它!
首先得搞清楚你遇到问题的根源:你现在导出的是已经实例化的React元素(就是<ComponentOne/>这种写法生成的对象),而不是组件本身。这就导致了:
- 用
map返回<component key={key}/>时,component是一个已经创建好的元素对象,不是组件类/函数,React会把它当成一个名为component的未知组件来渲染,自然没内容; - 直接给元素赋值
component.key = key不行,因为React元素是不可变对象,你没法直接修改它的属性。
下面给你两种既保留数组直观写法,又能正确添加key的方案:
方案一:导出组件类/函数数组(推荐,更灵活)
把组件列表文件改成导出组件本身,而不是实例化的元素。新手依然能一眼看到要包含的组件,而且后续还能灵活传递props:
// 组件列表文件 import React from 'react'; import ComponentOne from './ComponentOne'; // 导入组件 import ComponentTwo from './ComponentTwo'; // 导出组件类/函数的数组,而非实例化元素 export default [ComponentOne, ComponentTwo];
然后在Dashboard组件里,通过map遍历数组,创建元素并添加key:
// Dashboard组件 import React from 'react'; import components from './../../components'; export default class Dashboard extends React.Component { render = () => { return ( <div className="tile is-parent"> {components.map((Component, index) => { // 注意组件名要大写(React规范),这里用索引当key,若组件顺序固定没问题;如果会动态增减,建议用唯一ID return <Component key={index} />; })} </div> ); }; }
如果你的组件需要传递固定props,还可以把数组改成配置对象的形式,新手也能轻松理解:
// 组件列表文件 export default [ { component: ComponentOne, props: { title: '仪表盘组件1' } }, { component: ComponentTwo, props: { title: '仪表盘组件2' } } ];
然后Dashboard里这样渲染:
{components.map((item, index) => { const Component = item.component; return <Component {...item.props} key={index} />; })}
方案二:直接在导出的元素数组里添加key
如果你一定要导出已经实例化的元素数组(比如组件都带固定的props,不需要动态修改),可以直接在JSX里给每个元素加上key:
// 组件列表文件 import React from 'react'; import ComponentOne from './ComponentOne'; import ComponentTwo from './ComponentTwo'; // 导出时直接给每个元素添加key(用有意义的字符串比索引更好) export default [ <ComponentOne key="dashboard-component-1" />, <ComponentTwo key="dashboard-component-2" /> ];
然后Dashboard组件里直接渲染数组就可以了,不需要额外处理:
// Dashboard组件 import React from 'react'; import components from './../../components'; export default class Dashboard extends React.Component { render = () => { return ( <div className="tile is-parent"> {components} </div> ); }; }
这两种方案都能满足你保留数组写法的需求,而且完美解决key的问题~
内容的提问来源于stack exchange,提问作者bashleigh
相关产品推荐
相关产品推荐

