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]);
If you need the re render to be happened. You can store the array in a state. If you store the array in normal javascript variable. React will not re render the component. Try like I given below,
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.splice(2, 2));
}
}, [user]);
console.log(items);
return <Menu onClick={handleClick} selectedKeys={[current]} mode="horizontal" items={items} />;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.