skip to Main Content

I saw code like this:

export const ProModeContext = React.createContext({ 
   proMode: false
})

export class ActionButton extends Component {
   
   render() {
      return (
         <ProModeContext.Consumer>
            {contextData =>
               <button
                  disabled={!contextData.proMode}
                  onClick={this.props.callback}>
                  {this.props.text}
               </button>
            }
         </ProModeContext.Consumer>
      )
   }
}

I alway think we can only pass component inside a component only as:

<ComponentA>
   <ComponentB />
</ComponentA>

and we can get ComponentA’s children which is ComponentB

But how can we pass a function inside a rendered component/function as a child like:

<ComponentA>
   {() => console.log("Hello World")}
</ComponentA>

because when I try to get its children of ComponentA via this.props.children, it gets nothing, so the wrapped fucntion is not a child of ComponentA instance, so how does ProModeContext.Consumer takes a function as its child and apply this function internally?

2

Answers


  1. You can define children as render prop, that is a function taking parameters from parents.

    From the Legacy React Docs.

    The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function.
    A component with a render prop takes a function that returns a React element and calls it instead of implementing its own render logic.

    function ComponentA({children}) {
      const data = {}; // a state or data calculated by ComponentA
      return (
        <div>
          {children(data)}
        </div>
      );
    }
    

    Then you can use like this

    function Container() {
      return (
        <ComponentA>
          {(data) => <ComponentB data={data} />}
        </ComponentA>
    
      );
    }
    

    You can read more on this on Using props other than render and in the new React Docs Passing data with a render prop.

    Login or Signup to reply.
  2. The <ProModeContext.Consumer> component doesn’t directly take the function as its child. Instead, it uses the function as a child-rendering function. So basically the function returns a component that becomes the child of the <ProModeContext.Consumer> component

    In the given code, the function is used to dynamically render the button and handle its behavior based on the context value provided by the ProModeContext.

    <ComponentA>
       () => { ... }
    </ComponentA>
    

    In you example () => {}, will be rendered as part of the component’s output since it is plain text. To make it a function you need to enclose it between curly brackets like this:

    <ComponentA>
       { 
         () => { ... }
       }
    </ComponentA>
    

    The function simply allows us to to dynamically set the parent components child based on some condition.

    Here is a simple example:

    function App() {
        return (
           {
             login => { if (login) { return <HomePage> } else { return <LogIn> } }
           }
        )
    }
    

    The app component checks to see if the user has logged in, if they have, it renders the HomePage component. If not, it renders the LogIn component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search