如何向React组件传入类以创建实例实现子组件重写?
React动态传入组件渲染异常解决方案
问题原因
你的写法符合React的动态组件渲染设计,出现异常是JSX语法规则导致的:JSX中小写开头的标签会被识别为原生HTML标签,直接用<this.props.overrideClass />写法时,React不会将属性访问得到的组件类识别为自定义组件,因此会直接转为小写原生标签渲染,没有内容输出。
另外你提供的代码里存在拼写错误:Editor组件中传入的OverridenComponent比实际定义的类名OverriddenComponent少了一个字母r,也会导致渲染异常。
修复方案
只需要把props中拿到的组件类赋值给一个大写开头的变量,再用这个变量作为标签名渲染即可:
class Renderer extends React.Component{ render(){ // 赋值给大写开头的变量,符合JSX自定义组件规则 const OverrideComponent = this.props.overrideClass; return <OverrideComponent importantData="TEST"/>; } }
修改后渲染<Editor/>就可以正常输出<div>TEST</div>。
更灵活的可扩展方案
如果需要支持多组件覆盖、或者外部传入组件时需要额外添加自定义参数,推荐使用以下两种常用方案:
- 渲染属性(Render Props)模式
将需要动态渲染的部分定义为函数类型的props,Renderer调用该函数时把内部数据作为参数传入,外部可以自由决定渲染逻辑:
// Editor 侧用法 class Editor extends React.Component{ render(){ return ( <Renderer renderOverride={(importantData) => <OverriddenComponent importantData={importantData} extraProp="自定义参数"/>} /> ); } } // Renderer 侧用法 class Renderer extends React.Component{ render(){ const importantData = "TEST"; // 没有传入覆盖渲染时用默认组件 if (this.props.renderOverride) { return this.props.renderOverride(importantData); } return <DefaultComponent importantData={importantData} />; } }
- 函数型children模式
逻辑和渲染属性一致,只是把渲染函数放在children属性中,可读性更高:
// Editor 侧用法 class Editor extends React.Component{ render(){ return ( <Renderer> {(importantData) => <OverriddenComponent importantData={importantData} extraProp="自定义参数"/>} </Renderer> ); } } // Renderer 侧用法 class Renderer extends React.Component{ render(){ const importantData = "TEST"; if (typeof this.props.children === 'function') { return this.props.children(importantData); } return <DefaultComponent importantData={importantData} />; } }
内容的提问来源于stack exchange,提问作者cebo
相关产品推荐
相关产品推荐

