【问题标题】:Problem chaining Higher Order Components <Functions are not valid as a React child.>链接高阶组件的问题 <Functions are not valid as a React child.>
【发布时间】:2020-01-12 03:19:44
【问题描述】:

我创建了一个示例项目来演示我在尝试同时使用两个高阶组件 (hoc) 时遇到的问题。

首先是孤立的(没有错误)

=================================

第一个 hoc withStuff 接受一个注入的参数和一个 prop 并将 sum 传递给包装的组件。

// withStuff.js
const withStuff = ({argNumber}) => (BaseComponent) => ({propNumber, ...passThroughProps}) => {
  const sum = argNumber+propNumber
  return <BaseComponent sum={sum} {...passThroughProps} />
}

export default withStuff

第二个 hoc withExtra 采用注入函数并将结果加倍,将 double 传递给包装的组件。

// withExtra.js
const withExtra = (extraFunction) => (BaseComponent) => ({...passThroughProps}) => {
  const double = 2*extraFunction()
  return <BaseComponent double={double} {...passThroughProps} />
}

export default withExtra

这就是 Base 组件的使用方式,例如 withStuff(到目前为止一切正常)。

// Base.js
import withStuff from './withStuff'

const Base = ({content, sum}) => <div>{content} -sum:{sum}</div>

export default withStuff({argNumber:2})(Base)

==================================

现在问题来了:尝试在withStuff 中使用withExtra

import withExtra from './withExtra'

const withStuff = ({argNumber}) => (BaseComponent) => ({propNumber, ...passThroughProps}) => {
  const sum = argNumber+propNumber
  // this does not work
  return withExtra(()=>sum)(<BaseComponent sum={sum} {...passThroughProps}/>)
}

export default withStuff

这会返回一个错误:

Warning: Functions are not valid as a React child.

是不是因为现在withStuff 返回的是一个 hoc 函数而不是一个组件?该函数本身返回一个组件,所以我看不到问题所在。如何解决?

在此处注意代码沙盒:https://codesandbox.io/s/github/snirp/hoc-test

【问题讨论】:

    标签: reactjs react-redux higher-order-components


    【解决方案1】:

    withExtra应该得到一个组件,所以我认为这一行

    return withExtra(()=&gt;sum)(&lt;BaseComponent sum={sum} {...passThroughProps}/&gt;)

    应该是:

    return withExtra(()=&gt;sum)(BaseComponent)

    return withExtra(()=&gt;sum)(() =&gt; &lt;BaseComponent sum={sum} {...passThroughProps}/&gt;)

    【讨论】:

      【解决方案2】:

      问题在于您传递的是ReactElement 而不是组件。

      请参阅幕后what is JSX

      请注意,如果您想为给定的ReactElement 添加其他属性,您可以use cloneElement

      const withStuff = ({ argNumber }) => BaseComponent => ({
        propNumber,
        ...passThroughProps
      }) => {
        const sum = argNumber + propNumber;
      
        const callback = () => sum;
      
        // Like so you passing the node which leads to error
        // return withExtra(callback)(<BaseComponent sum={sum} {...passThroughProps}
      
        // Passing the reference
        return withExtra(callback)(BaseComponent);
      
        // Passing with additional props
        // return withExtra(callback)(React.cloneElement(BaseComponent, ...));
      
        // Equivalent
        // const WithExtraProps = withExtra(() => sum)(BaseComponent);
        // return <WithExtraProps sum={sum} {...passThroughProps} />;
      };
      

      【讨论】:

        【解决方案3】:

        您将 JSX 传递给 withExtra 不是组件,像这样更改 withStuff

        const withStuff = ({argNumber}) => (BaseComponent) => ({propNumber, ...passThroughProps}) => {
          const sum = argNumber+propNumber
        
          // this works
          // return <BaseComponent sum={sum} {...passThroughProps} />
        
          const WithExtraComponent = withExtra(()=>sum)(BaseComponent);
          return <WithExtraComponent sum={sum} {...passThroughProps}/>
        
        
        }
        

        https://codesandbox.io/s/hoc-test-pm02u

        【讨论】:

        • 感谢您添加代码框链接。我接受了这一点,但其他几个答案同样正确。
        【解决方案4】:

        这应该解决它:

        return withExtra(() => sum)(BaseComponent)();
        

        https://codesandbox.io/s/hoc-test-thxh0

        【讨论】:

          猜你喜欢
          • 2023-01-17
          • 2020-06-01
          • 2021-06-29
          • 2023-01-25
          • 1970-01-01
          • 2021-08-02
          • 2020-12-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多