高阶组件的问题:必须返回有效的 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'));
为什么 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'));