This is my first react project and I'm pretty sure I'm not managing state correctly but I don't know what to "google" 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
Any help getting my nose pointed inthe right direction would be much appreciated.
TIA
CodePudding user response:
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>
}