-1

This is my first React project and I'm pretty sure I'm not managing state correctly but I don't know what to search for for learning a better approach.

I have a parent / child component interaction. The parent passes a true or false to the child depending on user selection on the parent. The user can also make a choice in the child component (when visible) to change that same true or false variable.

I'm pretty sure I want to only manage that true / false state on the parent but I haven't been able to discover how to do that. This is the best I have come up with. On initial load everything works properly but subsequent interactions the parent no longer communicates with the child.

Parent Component:

const App = ()=> { const [drawerVisible, setDrawerVisible] = useState<boolean>(false); //useEffect(() => { setDrawerVisible(drawerVisible)}, [drawerVisible] ) const showDrawer = () => { console.log('App show drawer before: ' + drawerVisible); setDrawerVisible(true); console.log('App drawer after: ' + drawerVisible) }; return <Layout> <UserDrawer drawerVisible={drawerVisible} /> </Layout> }; export default App; 

Child Component:

interface DrawerVisible { drawerVisible:boolean } const UserDrawer = ({drawerVisible}:DrawerVisible) => { console.log('child passed in: ' + drawerVisible); const [drawerHidden, setDrawerHidden] = useState<boolean>(drawerVisible); useEffect(() => { setDrawerHidden(drawerVisible)}, [drawerVisible] ) const onClose = () => { setDrawerHidden(false); }; return <Drawer title="User Details" placement={'right'} closable={true} onClose={onClose} visible={drawerHidden} getContainer={false} style={{ position: 'absolute' }} > <Logout /> </Drawer> } export default UserDrawer; 

As I mentioned on initial load everything works. The console log shows correct values and the drawer shows.

Console Log:

App show drawer before: false App.tsx:47 App drawer after: false UserDrawer.tsx:10 child passed in: true UserDrawer.tsx:10 child passed in: true //Not sure why UserDrawer is being called twice? 

However subsequent interactions never get passed to the child.

Console Log:

//Clicked show drawer button 3 times App show drawer before: true App.tsx:47 App drawer after: true App.tsx:45 App show drawer before: true App.tsx:47 App drawer after: true App.tsx:45 App show drawer before: true App.tsx:47 App drawer after: true 

What can I try next?

2
  • @ankit-sanghvi Thank You! I knew I needed to manage state in one place but didn't know I could pass the parent useState to the child. Very cool. Thank you again. Commented Apr 12, 2022 at 17:17
  • Anytime @GPGVM :) Commented Apr 12, 2022 at 18:28

1 Answer 1

1

The reason this is happening is because you are controlling the same state from 2 different places. A simple solution would be to pass the setDrawerVisible also into your child component & use it there

The code for that is here

Parent Component

const App = ()=> { const [drawerVisible, setDrawerVisible] = useState<boolean>(false); const showDrawer = () => { console.log('App show drawer before: ' + drawerVisible); setDrawerVisible(true); console.log('App drawer after: ' + drawerVisible) }; return <Layout> <UserDrawer drawerVisible={drawerVisible} setDrawerVisible={setDrawerVisible} /> </Layout> }; export default App; 

Child Component

interface DrawerVisible { drawerVisible:boolean setDrawerVisible:Dispatch<SetStateAction<boolean>> } const UserDrawer:React.FC<DrawerVisible> = ({drawerVisible, setDrawerVisible}) => { const onClose = () => setDrawerVisible(false); return <Drawer title="User Details" placement={'right'} closable={true} onClose={onClose} visible={drawerVisible} getContainer={false} style={{ position: 'absolute' }} > <Logout /> </Drawer> } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.