javascript - 维护一个 React 组件列表然后渲染到父组件中
我有一个关于维护多态 React 组件数组的假设性问题。是否可能/是否是良好的 React 做法去维护一个继承自同一公共组件的组件数组,然后在容器中渲染它们?例如:
import * as React from 'react';
import GenericBlock from './GenericBlock';
import { BlockTypeA, BlockTypeB, BlockTypeC } from './MyBlocks';
export default class BlockHolder extends React.Component {
blocks : GenericBlock[] = [ <BlockTypeA />, <BlockTypeB />, <BlockTypeC /> ];
render() {
return (
<div id="workspace">
{
this.blocks
}
</div>);
};
};
通用块.tsx
import * as React from 'react';
export default class GenericBlock extends React.Component {
render() { return (<div></div>); }
}
MyBlocks.tsx:
import * as React from 'react';
import GenericBlock from './GenericBlock';
class BlockTypeA extends GenericBlock {
render() { return (<div></div>); }
};
class BlockTypeB extends GenericBlock {
render() { return (<div></div>); }
};
class BlockTypeC extends GenericBlock {
render() { return (<div></div>); }
};
export { BlockTypeA, BlockTypeB, BlockTypeC };
上述代码片段会产生错误:Objects are not valid as a React child,但我认为它捕捉到了我所说内容的精髓。有没有办法让上述方案可行?
我确定这个问题已经被问过并得到回答,但我似乎无法正确使用谷歌搜索。
编辑:
已添加沙箱链接: https://codesandbox.io/s/wizardly-wilson-vb7nn
现在我遇到了一个新错误:类型 'Element' 缺少类型 'GenericBlock' 的以下属性:render、context、setState、forceUpdate,以及另外两个。
编辑 2:
将 blocks 数组类型设为 JSX.Element 可以消除错误并让一切正常工作,但这似乎不是很好的做法,因为 JSX.Element 可以是任何元素,而将其类型设为 GenericBlock 的目的是确保所有元素都是特定组件的子孙组件。
答案#1
在 React 代码中,它运行得非常完美:https://codesandbox.io/s/optimistic-ptolemy-g25ge
无错误,无警告
import * as React from "react";
import { BlockTypeA, BlockTypeB, BlockTypeC } from "./MyBlocks";
export default class BlockHolder extends React.Component {
blocks = [
<BlockTypeA key={1} />,
<BlockTypeB key={2} />,
<BlockTypeC key={3} />
];
render() {
return <div id="workspace">{this.blocks}</div>;
}
}
import * as React from "react";
export default class GenericBlock extends React.Component {
render() {
return <div />;
}
}
import * as React from 'react';
import GenericBlock from './GenericBlock';
class BlockTypeA extends GenericBlock {
render() { return (<div>A</div>); }
};
class BlockTypeB extends GenericBlock {
render() { return (<div>B</div>); }
};
class BlockTypeC extends GenericBlock {
render() { return (<div>C</div>); }
};
export { BlockTypeA, BlockTypeB, BlockTypeC };
"dependencies": {
"react": "16.12.0",
"react-dom": "16.12.0",
"react-scripts": "3.0.1"
},
"devDependencies": {
"typescript": "3.8.3"
}
