我正在处理组件映射函数,该函数循环遍历具有type
键的对象列表。该函数返回一个React组件类型的对象,如下所示:
import _ from 'lodash';
import cellBodyTypes from './cellBodyTypes';
import {
GenericCellBody,
SubData
} from './components/CellBody';
const columnMapper = {};
_.forEach(cellBodyTypes, (type) => {
switch (type) {
case cellBodyTypes.SUB_DATA:
columnMapper[type] = SubData;
break;
case cellBodyTypes.DEFAULT:
columnMapper[type] = GenericCellBody;
break;
default:
columnMapper[type] = GenericCellBody;
}
});
export default columnMapper;
它的使用方式如下:
renderCellBody = (columnType, cellData, index) => {
const type = columnType || cellBodyTypes.DEFAULT;
const CellBodyComponent = columnMapper[type];
return <CellBodyComponent />;
}
渲染看起来像:
render (
<div>
{this.props.cellData.map((cell, index) => (
<div key={cell.id}>
{this.renderCellBody(cell.type, cell, index)}
</div>
))}
</div>
);
我想要做的是能够为使用与其他情况相同的React组件的新案例分配列类型,但是使用其他道具装饰这些新列类型。类似的东西:
case cellBodyTypes.NUMBER_SUB_DATA:
columnMapper[type] = React.cloneElement(SubData, {someAdditionalProp: 'something'});
break;
case cellBodyTypes.SINGLE_NUMBER:
columnMapper[type] = React.cloneElement(GenericCellBody, {someAdditionalProp: 'something'});
break;
我尝试使用React.cloneElement
返回React组件的克隆,但这不起作用,因为它给了我这个错误:React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.
有办法做到这一点吗?我接近正确的道路,只是遗漏了什么?感谢。
答案 0 :(得分:2)
这是因为React.cloneElement
返回的是反应元素,而不是组件。所以
columnMapper[type] = React.cloneElement(SubData,...
,
columnMapper[type]
将包含一个元素。
但问题是在renderCellBody
函数中,您试图通过编写
return <CellBodyComponent />;
这会引发错误。
我建议你保留columnMapper
elements
数组。所以switch/case
代码看起来应该是这样的
_.forEach(cellBodyTypes, (type) => {
switch (type) {
case cellBodyTypes.SUB_DATA:
// Store element instead of component
columnMapper[type] = <SubData />;
break;
case cellBodyTypes.DEFAULT:
// Store element instead of component
columnMapper[type] = <GenericCellBody />;
break;
case cellBodyTypes.NUMBER_SUB_DATA:
columnMapper[type] = React.cloneElement(SubData, {someAdditionalProp: 'something'});
break;
case cellBodyTypes.SINGLE_NUMBER:
columnMapper[type] = React.cloneElement(GenericCellBody, {someAdditionalProp: 'something'});
break;
default:
columnMapper[type] = <GenericCellBody />;
}
});
所以现在columnMapper
是elements
的数组。因此,在renderCellBody
函数中,您不需要再次将它们转换为element
。您只需返回值
renderCellBody = (columnType, cellData, index) => {
const type = columnType || cellBodyTypes.DEFAULT;
const CellBodyComponent = columnMapper[type];
// CellBodyComponent is already an element. So directly return it.
return CellBodyComponent;
}