Problem with reseting openKeys in Ant Design Menu within Sider

Viewed 3734

I have antd Menu inside collapsible Sider. I've set default open keys for one of Submenus and they should open one at a time. Here is my code for the Menu:

const MainMenu = ({ defaultOpenKeys }) => {
  const [openKeys, setOpenKeys] = useState(defaultOpenKeys);
  const rootKeys = ["sub1", "sub2"];
  // Open only one submenu at a time
  const onOpenChange = props => {
    const latestOpenKey = props.find(key => openKeys.indexOf(key) === -1);
    if (rootKeys.indexOf(latestOpenKey) === -1) {
      setOpenKeys(props);
    } else {
      setOpenKeys(latestOpenKey ? [latestOpenKey] : defaultOpenKeys);
    }
  };
  return (
    <Menu
      theme="dark"
      openKeys={openKeys}
      defaultSelectedKeys={["1"]}
      mode="inline"
      onOpenChange={onOpenChange}
    >
      <Menu.Item key="1">
        Option 1
      </Menu.Item>
      <SubMenu key="sub1" title="User">
        <Menu.Item key="2">Tom</Menu.Item>
      </SubMenu>
      <SubMenu key="sub2" title="Team">
        <Menu.Item key="3">Team 1</Menu.Item>
      </SubMenu>
    </Menu>
  );
};

export default MainMenu;

I pass defaultOpenKeys from the Sider.

const SiderDemo = () => {
  const [collapsed, setCollapsed] = useState(false);
  const toggleSider = () => {
    setCollapsed(!collapsed);
  };
  return (
    <Layout style={{ minHeight: "100vh" }}>
      <Button type="primary" onClick={toggleSider}>
        {React.createElement(
          collapsed ? MenuFoldOutlined : MenuUnfoldOutlined
        )}
      </Button>
      <Sider
        collapsible
        collapsed={collapsed}
        collapsedWidth={0}
        trigger={null}
      >
        <Menu defaultOpenKeys={["sub1"]} />
      </Sider>
      ...
    </Layout>
  );
};

It works on mount, but when I collapse the Sider, defaultOpenKeys are being reset. How can I keep defaultOpenKeys from being reset, when the Sider is collapsed?

I have created a codesandbox and added console log in the Menu. You can see that defaultOpenKeys and openKeys are the same on mount. When I collapse the Sider, the console log is triggered twice. The first time defaultOpenKeys and openKeys are the same. And the second time openKeys become empty. How can I fix that?

1 Answers

Reason: on closing the sidebar it is closing opened sidemenu so it gonna trigger openchange with empty array and hence your logic making it reset to empty.

Here is code sandbox link with updated code

https://codesandbox.io/s/sider-demo-0der5?file=/Menu.jsx

Suggestion: Its anti pattern to assign props to initial state. if prop value changed in parent component then the new prop value will never be displayed because intial state will never update the current state of the component. The initialization of state from props only runs when the component is first created

Related