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'))
更新了这里的演示感谢这是一个datagridfilterComponents
,用户需要将一个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 {}
}