Search code examples
reactjsreact-propshigher-order-components

Functional Component's props in Higher Order Component


I am trying to understand passing the functional component's props to the returned functional component

**CODE ------------------------------------------------

App Component:

import React from 'react';
import ClickCounter from './ClickCounter';

const App = () => {
  return (
    <div className="App">
      <ClickCounter firstName="John" lastName="Doe"/>
    </div>
  );
}

export default App;

ClickCounter Component:

import React from 'react'
import withCounter from './withCounter'

const ClickCounter = (props) => {

  const { count, incrementCount, name } = props

  return (
    <div className="click-counter">
      <button onClick={incrementCount}>Click Button</button>
      <h2>{name}</h2>
      <h1>{count}</h1>
    </div>
  )
}

export default withCounter(ClickCounter, 10)

withCounter Component (HOC)

import React, { useState } from 'react'


const withCounter = (WrappedComponent, incrementNumber) => {
  return props => {           // ** A **
    console.log('props  ---- ', props)
    const [count, setCount] = useState(0)

    return (
      <WrappedComponent.      // ** B **
        count={count}
        incrementCount={() => setCount(count + incrementNumber)}
        {...props}
      />
    )
  }
}

export default withCounter

From my understanding, the withCounter return a functional component (A) that use useState Hook and and it return another component (B) which access the state through closure.

** QUESTION -------------------------------------------

My question is why the props in A is firstName="John" lastName="Doe", is it a React thing or Javascript's thing.

Does React pass the parameter's props (i.e wrapped component's props) to the returned functional component? or it is a Javascript's thing?

i read it in another post saying it is related to curry, but i cannot see it is related to curry, below is the post i read

HoC with React Hooks

const useSample = WrappedComponent => props => { // curry
  const sampleCtx = useContext(SampleCtx);
  return (
    <WrappedComponent
      {...props}
      value={sampleCtx.value}
      setValue={sampleCtx.setValue}
    />
  );
};

Thank you!!


Solution

  • My question is why the props in A is firstName="John" lastName="Doe", is it a React thing or Javascript's thing.

    This is because that's the props you passed to your Counter. Attributes on a component are props passed to functional components. This is a React thing.

    <ClickCounter firstName="John" lastName="Doe"/>
    

    When you put the component ClickCounter in your tree, it's actually just withCounter(ClickCounter, 10) being called, since that's your default export.

    withCounter is a function that returns another function (curry) that takes props and returns a component. This is the setup for a functional component.

    React runs this function and passes the props firstName="John" lastName="Doe" to that function. Then, those props are added to your WrappedComponent via the spread operator {...props}.