Guys I'm working on a project now and I have a component that is returned by antd Menu
item. It has 4 components: Home
, Username
, Login
, and Register
:
const items = [
{
label: <Link to='/'>Home </Link>, //- {JSON.stringify(user)}
key: 'home',
icon: <AppstoreOutlined />,
},
{
label: 'Username',
key: 'SubMenu',
icon: <SettingOutlined />,
children: [
{
label: 'Option 1',
key: 'setting:1',
},
{
label: 'Option 2',
key: 'setting:2',
},
{
label: <item onClick={logout}>Logout</item>,
key: 'setting:3',
icon: <LogoutOutlined />
},
],
},
{
label: <Link to='/register'>Register</Link>,
key: 'register',
icon: <UserAddOutlined />,
style: { marginLeft: 1030}, // problem: hard-coded margin
},
{
label: <Link to='/login'>Login</Link>,
key: 'login',
icon: <UserOutlined />,
style: { marginLeft: 'auto'},
},
];
useEffect(() => {
if (user) { // "user" is an object returned by userSelector
items.splice(2, 2);
}
}, [user]);
console.log(items);
return <Menu onClick={handleClick} selectedKeys={[current]} mode="horizontal" items={items} />;
As you can see, I'm using a useEffect
hook here. If the user is not logged in (so user === null
), then the if statements in useEffect
will not be executed; otherwise the Login
and Register
components in the array items
will be removed and hidden, and only the first 2 are left.
From console.log(items);
we can see what items
is like currently. When a user is logged in, it does have only two components:
However, we can still see Login
and Register
are there in such a circumstance:
So why do JS and React render removed components?
You need to use "useState" hook to make the UI update, in you example, the items will be updated, but the UI will not update.
import { useState } from 'react'
const [items, setItems] = useState([
{
label: <Link to='/'>Home </Link>, //- {JSON.stringify(user)}
key: 'home',
icon: <AppstoreOutlined />,
},
{
label: 'Username',
key: 'SubMenu',
icon: <SettingOutlined />,
children: [
{
label: 'Option 1',
key: 'setting:1',
},
{
label: 'Option 2',
key: 'setting:2',
},
{
label: <item onClick={logout}>Logout</item>,
key: 'setting:3',
icon: <LogoutOutlined />
},
],
},
{
label: <Link to='/register'>Register</Link>,
key: 'register',
icon: <UserAddOutlined />,
style: { marginLeft: 1030}, // problem: hard-coded margin
},
{
label: <Link to='/login'>Login</Link>,
key: 'login',
icon: <UserOutlined />,
style: { marginLeft: 'auto'},
},
]);
useEffect(() => {
if (user) { // "user" is an object returned by userSelector
setItems((items) => {
items.splice(2, 2);
return items;
}
}
}, [user]);