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

Issue with higher order components: A valid React element (or null) must be returned

为什么 higherOrderComponent1 功能不起作用,而 higgerOrderComponent2 功能正常?根据文档,我似乎没有做错什么,但由于它不起作用,我一定是做错了什么:-)

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 属性 将传递给包装的组件,因为返回的 <WrappedComponent /> 调用的 <WrappedComponent /> 调用 { ...props } class 来自 HOC.

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

我正在调用 giveColor HOC,其中 PrintName 组件作为第一个参数,我想要设置的颜色作为第二个参数。

在 HOC 中,我将 WrappedComponent 包装在一个 div 中,我给出一个 ref,我用它来更改第一个 [=43] 的 style.color 属性 =] 的 ref.

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

HOC 的一些很好的例子是 react-redux and withRouter() from react-router

中的 connect()

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

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

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'));