2

I'm quite new to functional components and I've been on this for hours. I simply want to pass a prop from a parent functional component to a class child component so that I will use the updated prop (which will be a boolean) to change the display of an element. That's all.

In this scenario, I want to switch the sidenav from opened to closed based on the prop.

Here is the parent component (functional):

   let opened = false;

   function openSidenav(){
       opened = !opened;
   }
   const [sidebarOpened, setOpened ] = useState(opened);

   return (
       <Sidebar sidebarOpened={opened} />
   )

and the child component (class):

   componentDidUpdate(prevProps) {
      if(this.props.sidebarOpened !== prevProps){
         this.setState({ sidebar: true});
      }
   }

It's just not working, the child component isn't receiving changes, I guess I didn't pass the prop rightly. I know the code just needs correction but I don't know where I'm not getting it.

Thank you.

Olawale Oladiran
  • 561
  • 2
  • 11
  • 19

2 Answers2

3

The argument to useState is only used once. You need to set the state in openSidenav function to trigger a re-render.

Parent


   function openSidenav(){
       setOpened(prev => !prev);
   }
   const [sidebarOpened, setOpened ] = useState(false);

   return (
       <Sidebar sidebarOpened={sidebarOpened} />
   )

Also in child component, use prevProps.sidebarOpened (not just prevProps).

Child

componentDidUpdate(prevProps) {
      if(this.props.sidebarOpened !== prevProps.sidebarOpened){ //<---- see here
         this.setState({ sidebar: this.props.sidebarOpened});//<---- see here
      }
   }

p.s - Also, since you are using props directly in child component, you can consider to not to copy props into state.

gdh
  • 13,114
  • 2
  • 16
  • 28
1

In parent,

  const [sidebarOpened, setOpened ] = useState(false);

  function openSidenav(){
    setOpened(!sidebarOpened);
  }

  return (
    <Sidebar sidebarOpened={sidebarOpened} />
  )

And in child component class directly use this.props.sidebarOpened instead of copying over the prop to state. If you intend to edit the value of sidebarOpened in the child component, pass setOpened to the child component as a prop and use that to edit the value.

Karthick Vinod
  • 1,237
  • 8
  • 11
  • That `setOpened(!opened)` method only worked once (the first time), it didn't work in the subsequent clicks. I guess that's the only difference in your answer and the accepted one. Thank you. – Olawale Oladiran May 25 '20 at 04:16
  • 1
    You are correct. the openSidenav() fn must be setOpened(!sidebarOpened). Changed my answer. – Karthick Vinod May 25 '20 at 04:20