Javascript 将功能组件呈现为JSX会中断渲染协调

Javascript 将功能组件呈现为JSX会中断渲染协调,javascript,reactjs,Javascript,Reactjs,我希望我的组件的用户能够传入组件的对象,并且我希望允许他们使用功能性或基于类的组件 type InputComponents = Record<string, React.ComponentType> Typescript甚至不认为渲染组件的有效方式,但它是唯一完全工作的方式……它错误为“This expression is not callable.”并且类组件也失败,因此我必须这样做: // Render as JSX for class components and cal

我希望我的组件的用户能够传入组件的对象,并且我希望允许他们使用功能性或基于类的组件

type InputComponents = Record<string,  React.ComponentType>
Typescript甚至不认为渲染组件的有效方式,但它是唯一完全工作的方式……它错误为“This expression is not callable.”并且类组件也失败,因此我必须这样做:

// Render as JSX for class components and call as a function for FC ones...
Component.prototype.isReactComponent ? <Component placeholder={x} /> : Component({ placeholder: x })
//类组件呈现为JSX,FC组件调用为函数。。。
Component.prototype.isReactComponent?:组件({占位符:x})
您可以在此处看到实际问题:

函数SomeComponent({inputComponents}){
常数B=输入组件.B;
常数C=输入组件.C;
返回(
此FC组件不会失去焦点:

{inputComponents.a({占位符:'键入某物'})} 这个是:

将类组件呈现为JSX仍然有效:

); } 类InputClass扩展了React.Component{ 状态={ 值:“” }; render(){ 返回( { this.setState({value:e.currentTarget.value}); }} /> ); } } 函数App(){ 常量[状态,设置状态]=React.useState({ a:“”, b:' }); 常量输入组件={ a:({占位符})=>( { 常量值=e.currentTarget.value; setState((s)=>({…s,a:value})); }} /> ), b:({占位符})=>( { 常量值=e.currentTarget.value; setState((s)=>({…s,b:value})); }} /> ), c:输入类 }; 返回( ); } ReactDOM.render(,document.getElementById('app'))

问题在于,您在每次重新加载时都会创建一个新组件(函数本身),因为您在
应用程序中有
inputComponents
。如果将类声明移动到内部范围,则类组件也会发生相同的行为

inputComponent = {
  c: class InputClass extends Component {}
}
要解决此问题,您可以将组件映射到外部范围,并将
state
setState
作为道具传递。或者通过上下文提供

函数SomeComponent({inputComponents,args}){
常数B=输入组件.B;
常数C=输入组件.C;
返回(
这个是:

将类组件呈现为JSX仍然有效:

); } 类InputClass扩展了React.Component{ 状态={ 值:“” }; render(){ 返回( { this.setState({value:e.currentTarget.value}); }} /> ); } } 常量输入组件={ b:({占位符,状态,设置状态})=>( { 常量值=e.currentTarget.value; setState((s)=>({…s,b:value})); }} /> ), c:输入类 }; 函数App(){ 常量[状态,设置状态]=React.useState({ a:“”, b:' }); 返回( ); } ReactDOM.render(,document.getElementById('app'))


更新了这里的演示感谢这是一个datagrid
filterComponents
,用户需要将一个
filterState
对象传递到另一个钩子中,因此他们可能会定义内部组件以访问该状态,但是在每次按键时状态改变时,包装
useMemo
将无法工作。也许我可以想出一个更好的设计,但我也不想依赖我的用户做聪明的事情。我有一个解决办法,将FC组件作为函数进行检测和调用,但我发现我不能通过正常的JSX方式调用它们,这很奇怪。无论如何+1“我有一个变通方法,将FC组件称为函数”,我建议不要将其称为组件。叫它。如果用户想要使用类组件,他们仍然可以将其作为渲染道具传递
c:(args)=>
谢谢我这样做,而且它可以正常工作
inputComponents.a({ placeholder: 'Type something' })
// Render as JSX for class components and call as a function for FC ones...
Component.prototype.isReactComponent ? <Component placeholder={x} /> : Component({ placeholder: x })
inputComponent = {
  c: class InputClass extends Component {}
}