React抱怨说,当我的组件被传递到另一个组件中进行渲染时,钩子没有在主体函数内部使用



我有一个组件,它使用另一个组件作为渲染器。然而,React不允许我在渲染器组件中使用钩子,因为它会抛出以下错误:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

以下是我的显示组件中的一个示例,它是一个错误边界

class DisplayComponent extends Component {
// ...
render() {
const { rendererComponent } = this.props;
return rendererComponent({ enabled: true, name: 'hello-world' })
}
}

正如您所看到的,DisplayComponent中的rendererComponent道具是作为一个函数调用的,尽管它是一个组件,并且我在这样调用它时将一些道具传递给它。

现在,在我使用DisplayComponent的另一个文件中,它看起来像这样:

const RendererComponent = (props) => {
const { enabled, name } = props;
const [testState, setTestState] = useState(); // Error: Invalid hook call
useEffect(() => {
// Error: Invalid hook call
}, [testState]);
return (
<div>{name} - {enabled}</div>
)
}
const App = () => {
return (
<DisplayComponent rendererComponent={RendererComponent} />
)
}

这是关键。由于某些原因,我不能在RendererComponent中使用useEffectuseState等钩子。如果我使用它,React会抛出我上面提到的钩子无效的错误。但是我想要一些需要RendererComponent中钩子的逻辑。

我如何使用钩子来在一个组件中产生状态和效果,而这个组件是以我的方式调用的?

您正在进行函数调用,而不是安装组件,这是两种不同的调用和语法,请将其更改为:

class DisplayComponent extends Component {
render() {
// Custom component must be Capitalized
const { rendererComponent: RenderedComponent } = this.props;
return <RenderedComponent enabled name="hello-world" />;
}
}
// Notice that the JSX is transpiled to
React.createElement(RenderedComponent, {
enabled: true,
name: "hello-world"
});

在React中,您只能通过用React.createElement调用其API来装载组件(JSX是其糖语法(,而简单的函数调用则是纯粹的JS,它不会触发React API,即不会将组件注册到组件树中。因此,像hook这样的内部实现没有任何意义,您将在每次渲染时丢失状态(不会触发Recommendation(。

最新更新