React - 'Do not use HOC’s in the render method of a component. Access the HOC outside the component definition.' 是什么意思?
React - What is meant by 'Do not use HOC’s in the render method of a component. Access the HOC outside the component definition.'?
我正在学习 HOC 并一直在阅读上面的引用,但我不明白它的意思。如果我的 HOC 向我的消费组件添加了一个方法,我可以像这样在渲染方法中使用该方法吗?如果不是,我将如何做我想在这里做的事情:
import React, { Component } from 'react';
import { withMyHOC } from '../with_my_component'
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default withMyHOC(MyComponent );
当你说不要在 render 方法中使用 HOC 时,这意味着你不应该在另一个组件的 render 方法中创建 HOC 包装的组件的实例。例如,如果你有一个使用 MyComponent 的 App 组件,它不应该像下面这样
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default MyComponent;
import { withMyHOC } from '../with_my_component'
export default class App extends React.Component {
render() {
const Wrap = withMyHOC(MyComponent);
return (
<div>
{/* Other Code */}
<Wrap />
</div>
)
}
}
为什么你不应该像上面那样使用它是因为每次调用 render 方法时,都会创建一个 MyComponent
的新实例,由名为 Wrap
的 HOC 包装,因此每次都会再次安装它而不是通过自然生命周期或 React。
但是,如果您的 HOC 将函数作为 props 传递,您可以在渲染中使用它,只要它不会再次导致重新渲染,否则会导致无限循环。
另外,直接在render中调用的函数最好memoize,避免反复计算
A High Order Component
是 function
,而 returns 是 Component
,而不是 jsx
。使用 hoc 包装组件时,您并没有更改组件的返回值,而是更改了签名本身。考虑以下 hoc
const withFoo = Component => props =>{
return <Component {...props} foo='foo' />
}
withFoo
是一个 function
,它将 Component
(不是 jsx
)作为参数,returns 是一个组件。您不需要从 render 调用 hoc
,因为它注入的值已经在包装组件的 props
中。
hoc
告诉包装组件的外观,更改它的定义,因此唯一可以使用它的地方是在组件定义本身。在 render 中调用 hoc
会在每个 render 上创建该组件的新实例。相当于
const Component = () =>{
const ChildComponent = () =>{
return <span> Child </span>
}
return <ChildComponent /> //You're declaring again on each render
}
像这样使用你的高阶组件
const Component = ({ foo }) => <div>{ foo }</div>
export default withFoo(Component)
或
const Component = withFoo(({ foo }) => <div>{ foo }</div>)
我正在学习 HOC 并一直在阅读上面的引用,但我不明白它的意思。如果我的 HOC 向我的消费组件添加了一个方法,我可以像这样在渲染方法中使用该方法吗?如果不是,我将如何做我想在这里做的事情:
import React, { Component } from 'react';
import { withMyHOC } from '../with_my_component'
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default withMyHOC(MyComponent );
当你说不要在 render 方法中使用 HOC 时,这意味着你不应该在另一个组件的 render 方法中创建 HOC 包装的组件的实例。例如,如果你有一个使用 MyComponent 的 App 组件,它不应该像下面这样
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default MyComponent;
import { withMyHOC } from '../with_my_component'
export default class App extends React.Component {
render() {
const Wrap = withMyHOC(MyComponent);
return (
<div>
{/* Other Code */}
<Wrap />
</div>
)
}
}
为什么你不应该像上面那样使用它是因为每次调用 render 方法时,都会创建一个 MyComponent
的新实例,由名为 Wrap
的 HOC 包装,因此每次都会再次安装它而不是通过自然生命周期或 React。
但是,如果您的 HOC 将函数作为 props 传递,您可以在渲染中使用它,只要它不会再次导致重新渲染,否则会导致无限循环。
另外,直接在render中调用的函数最好memoize,避免反复计算
A High Order Component
是 function
,而 returns 是 Component
,而不是 jsx
。使用 hoc 包装组件时,您并没有更改组件的返回值,而是更改了签名本身。考虑以下 hoc
const withFoo = Component => props =>{
return <Component {...props} foo='foo' />
}
withFoo
是一个 function
,它将 Component
(不是 jsx
)作为参数,returns 是一个组件。您不需要从 render 调用 hoc
,因为它注入的值已经在包装组件的 props
中。
hoc
告诉包装组件的外观,更改它的定义,因此唯一可以使用它的地方是在组件定义本身。在 render 中调用 hoc
会在每个 render 上创建该组件的新实例。相当于
const Component = () =>{
const ChildComponent = () =>{
return <span> Child </span>
}
return <ChildComponent /> //You're declaring again on each render
}
像这样使用你的高阶组件
const Component = ({ foo }) => <div>{ foo }</div>
export default withFoo(Component)
或
const Component = withFoo(({ foo }) => <div>{ foo }</div>)