ken
ken

Reputation: 2662

How to pass a function as props when both Parent and Child component also a functional component?

I have this ParentComponent which I want to pass a function named toggleDrawer to the ChildComponent like this:

const ParentComponent = () {
     
   const [drawerState, setDrawerState] = useState(false);

   const toggleDrawer = (anchor, open) => {
        setDrawerState(open);
   }

  return(
       <div>
         <IconButton color="primary"                         
                     onClick={toggleDrawer("right", true)}> // here I called to toggleDrawer so the ChildComponent can be shown 
             <SomeIcon />
         </IconButton>
         
        <ChildComponent 
             anchor="right"
             open={drawerState}
             handleDrawerState={toggleDrawer}/> 

        </div>
  )
}

So I get the toggleDrawer function in ChildComponent like this:

const CartDrawer = (props) => {

 // other stuff at the top 

 return(
    <Drawer
      anchor={props.anchor}
      open={props.open}
      onClose={props.handleDrawerState(props.anchor, false)}
    >
  )
}

As you can see I get the handleDrawerState in ChildComponent by accessing it props. But what I get is:

TypeError: props.handleDrawerState is not a function

I tried below, also get the same result:

const {handleDrawerState} = props

 <Drawer
       ... other stuff 
   onClose={handleDrawerState(props.anchor, false)}
>

So I check the console in browser by console.log(props) , instead having a key with handleDrawerState, I having a object in the props ,which present like this:

proto: Object

For now, I not understand what I doing wrong, cause as I see here, toggleDrawer in ParentComponent is a function, but passed to ChildComponent it become and object. Therefore I unable to access it in props in ChildComponent .

Question:

Therefore, what is the correct way to pass a function to ChildComponent ?

Updated:

If I do like this :

<Drawer
    ... some other stuff 
    onClose={() => props.handleDrawerState(props.anchor, false)}
>

I get the error like this:

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

Upvotes: 3

Views: 537

Answers (1)

Joe Lloyd
Joe Lloyd

Reputation: 22363

They need to be wrapped in an anon function

You cannot call a function as a prop if you fire the function when adding it as a prop (unless you want the result of the fired function passed as a prop).

Should be this

const ParentComponent = () {
     
   const [drawerState, setDrawerState] = useState(false);

   const toggleDrawer = (anchor, open) => {
        setDrawerState(open);
   }

  return(
       <div>
         <IconButton color="primary"                         
                     onClick={() => toggleDrawer("right", true)}> //anon func here
             <SomeIcon />
         </IconButton>
         
        <CartDrawer 
             anchor="right"
             open={drawerState}
             handleDrawerState={toggleDrawer}/> 

        </div>
  )
}

const CartDrawer = (props) => {

 // other stuff at the top 

 return(
    <Drawer
      anchor={props.anchor}
      open={props.open}
      onClose={() => props.handleDrawerState(props.anchor, false)} // annon func here
    />
  )
}

The way you have it right now it will fire only once when the component mounts.

<MyComponent 
  onClick={handleClick()} // this will always fire on mount, never do this unless you want the result from the function as a prop and not the function as itself
/>

Upvotes: 1

Related Questions