简体   繁体   中英

why does javascript render removed components

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM