admin管理员组文章数量:1305157
I'm working on a ponent mapping function that loops through a list of objects which have a type
key. The function returns an object of types of React ponents, it looks like this:
import _ from 'lodash';
import cellBodyTypes from './cellBodyTypes';
import {
GenericCellBody,
SubData
} from './ponents/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;
And it's used like this:
renderCellBody = (columnType, cellData, index) => {
const type = columnType || cellBodyTypes.DEFAULT;
const CellBodyComponent = columnMapper[type];
return <CellBodyComponent />;
}
And the render looks something like:
render (
<div>
{this.props.cellData.map((cell, index) => (
<div key={cell.id}>
{this.renderCellBody(cell.type, cell, index)}
</div>
))}
</div>
);
What I want to do is to be able to assign column types for new cases which utilize the same React ponents as other cases, but decorate those new column types with additional props. Something like:
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;
I tried returning a clone of the React ponent using React.cloneElement
but that does not work, as it gives me this error: React.createElement: type is invalid -- expected a string (for built-in ponents) or a class/function (for posite ponents) but got: object.
Is there a way to do this? Am I close to the right path and just missing something? Thanks.
I'm working on a ponent mapping function that loops through a list of objects which have a type
key. The function returns an object of types of React ponents, it looks like this:
import _ from 'lodash';
import cellBodyTypes from './cellBodyTypes';
import {
GenericCellBody,
SubData
} from './ponents/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;
And it's used like this:
renderCellBody = (columnType, cellData, index) => {
const type = columnType || cellBodyTypes.DEFAULT;
const CellBodyComponent = columnMapper[type];
return <CellBodyComponent />;
}
And the render looks something like:
render (
<div>
{this.props.cellData.map((cell, index) => (
<div key={cell.id}>
{this.renderCellBody(cell.type, cell, index)}
</div>
))}
</div>
);
What I want to do is to be able to assign column types for new cases which utilize the same React ponents as other cases, but decorate those new column types with additional props. Something like:
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;
I tried returning a clone of the React ponent using React.cloneElement
but that does not work, as it gives me this error: React.createElement: type is invalid -- expected a string (for built-in ponents) or a class/function (for posite ponents) but got: object.
Is there a way to do this? Am I close to the right path and just missing something? Thanks.
Share Improve this question edited Mar 5, 2018 at 19:03 Austin Knight asked Mar 5, 2018 at 18:55 Austin KnightAustin Knight 1031 gold badge1 silver badge8 bronze badges 2-
this.props.cellData.map((cell, index) => ( <div key={cell.id}> ... ))
– dfsq Commented Mar 5, 2018 at 19:00 - @dfsq Thanks, that was a typo in the pseudo code I used, I know thats not the issue – Austin Knight Commented Mar 5, 2018 at 19:03
1 Answer
Reset to default 5That is because React.cloneElement
return a react element, not ponent. So after
columnMapper[type] = React.cloneElement(SubData,...
,
columnMapper[type]
will containt an element.
But problem is that in renderCellBody
function, you are trying to convert an element again into element by writing
return <CellBodyComponent />;
And that throws an error.
I would suggest that you keep columnMapper
an array of elements
. So the switch/case
code should look something like this
_.forEach(cellBodyTypes, (type) => {
switch (type) {
case cellBodyTypes.SUB_DATA:
// Store element instead of ponent
columnMapper[type] = <SubData />;
break;
case cellBodyTypes.DEFAULT:
// Store element instead of ponent
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 />;
}
});
So now columnMapper
is an array of elements
. Therefore in renderCellBody
function, you don't need to convert them into element
again. You can simply return the value
renderCellBody = (columnType, cellData, index) => {
const type = columnType || cellBodyTypes.DEFAULT;
const CellBodyComponent = columnMapper[type];
// CellBodyComponent is already an element. So directly return it.
return CellBodyComponent;
}
本文标签: javascriptAssign a React component to a variable with extra propsStack Overflow
版权声明:本文标题:javascript - Assign a React component to a variable with extra props - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741798336a2398071.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论