高阶组件的问题:必须返回有效的 React 元素(或 null)



为什么highOrderComponent1函数不起作用,而highOrderComponent2按预期工作?根据文档,我似乎没有做错什么,但由于它不起作用,我一定做错了什么:-(

https://facebook.github.io/react/docs/higher-order-components.html

您可以在此处找到沙盒版本: https://codesandbox.io/s/MRwMnA2R

import React, {Component} from 'react';
import {render} from 'react-dom';
const higherOrderComponent1 = (name) => {
return class extends Component {
render() {
<div>{`Hi ${name}`}</div>
}
}
};
const higherOrderComponent2 = (name) => (
<div>{`Hi ${name}`}</div>
);

const App = () => (
higherOrderComponent1("Peter")
);
render(<App />, document.getElementById('root'));

好的,您对如何使用 HOC 有点不对劲。这是一个简单的例子,我将解释一下。

function giveColor( WrappedComponent, color ) {
return class extends Component {    
componentDidMount() {
this.wrapperEl.children[ 0 ].style.color = color;
}
render() {
console.log(this.props)
return (
<div ref={ ( el ) => this.wrapperEl = el }>
<WrappedComponent { ...this.props } />
</div>
);
}
}
}
const PrintName = ({ name }) => (
<div>{ name }</div>
);
const PrintRedName = giveColor( PrintName, "#ff0000" );

您将按如下方式使用 PrintRedName:<PrintRedName name="Bubowski" />

您提供的name属性将传递到包装的组件,因为从 HOC 返回的类的 render 方法中的<WrappedComponent />调用{ ...props }

HOC 用作另一个组件上的函数,如下所示:const PrintRedName = giveColor( PrintName, "#ff0000" );

我调用 giveColor HOC 将 PrintName 组件作为第一个参数,并将要设置的颜色设置为第二个参数。

在 HOC 中,我将包装组件包装在一个div 中,我给出了一个ref,用于更改ref的第一个子项的 style.color 属性。

这是一个人为的例子,但我希望它能帮助你理解:)

HOC的一些很好的例子是从react-reduxconnect()的,withRouter()来自react-router的。

编辑:回答您的最新问题:

我编辑了您链接到以下内容的代码以使其工作,请阅读代码注释。

const wrapComponent = (WrappedComponent) =>
class extends Component {
render() {
return (
<div>
I wrapped:
<WrappedComponent {...this.props} />
</div>
)
}
}
const ComponentA = ({name}) => <div><b>{name}</b></div>;
const ComponentB = wrapComponent(ComponentA);
// You had...
/*
No need to wrap a component wrapping itself, but the problem here is,
You're nesting evalutions by doing { ...code } inside
() => ( single evaluation )
const App = () => (
{ wrapComponent(ComponentB) }
)
*/

const App = () => (
<ComponentB name="My name" />
)
render(<App />, document.getElementById('root'));

最新更新