Ad

Problem Chaining Higher Order Components

- 1 answer

I created a sample project to demonstrate a problem I have when trying to use two Higher Order Components (hoc) together.

First in isolation (no errors)

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

The first hoc withStuff takes an injected argument and a prop and passes the sum to the wrapped component.

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

export default withStuff

The second hoc withExtra takes an injected function and doubles the result, passing double to the wrapped component.

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

export default withExtra

This is how a Base component would use for instance withStuff (all working fine so far).

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

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

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

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

Now comes the problem: trying to use withExtra inside withStuff:

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

This returns an error:

Warning: Functions are not valid as a React child.

Is it because now withStuff is returning a hoc function instead of a component? That function returns a component itself, so I cannot see the problem. How to solve this?

NOTE CODESANDBOX HERE: https://codesandbox.io/s/github/snirp/hoc-test

Ad

Answer

Your passing JSX to withExtra not a component, Change withStuff like this :

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

Ad
source: stackoverflow.com
Ad