Home > Blockchain >  why does javascript render removed components
why does javascript render removed components

Time:06-19

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 useing 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 array itemswill be removed and hided, 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: enter image description here

However we can still see Login and Register are there in such a circumastance: enter image description here

So why do js and react render removed components?

CodePudding user response:

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]);

CodePudding user response:

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} />;
  • Related