react-component / menu

React Menu
https://menu.react-component.now.sh/
MIT License
681 stars 247 forks source link

Menu.Item和Menu. SubMenu的key属性值被react改变,导致无法在外部操纵菜单展开和选中 #87

Closed hzq1988a closed 7 years ago

hzq1988a commented 7 years ago

如题,key值的前面被加上若干.$,react版本为15.5.4

paranoidjk commented 7 years ago

key 不是普通属性,key 是交给 react 内部使用的。

paranoidjk commented 7 years ago

https://facebook.github.io/react/docs/lists-and-keys.html#keys

hzq1988a commented 7 years ago

@paranoidjk 不好意思,之前提供的信息不全,当我单独使用menu的时候,是没问题的,但是加上 react-css-modules 之后就会出现此问题 image image

paranoidjk commented 7 years ago

React will escape key for internal use as reactid, but when you try to access, it will unescape, so i think there is no need to worry.

User-specified keys undergo an escaping transformation to prevent collisions with automatically-generated keys. auto-generated keys are completely internal (never user visible) and are guaranteed to never conflict (because they are generated, and user keys are escaped)

https://github.com/facebook/react/blob/master/src/shared/utils/__tests__/KeyEscapeUtils-test.js facebook/react#6475

hzq1988a commented 7 years ago

但是使用Menu.Item和Menu. SubMenu中的props需要传key值,我把代码贴一下吧。


import React from 'react'
import ReactDOM from 'react-dom';
import CSSModules from 'react-css-modules'
import { Menu, Icon } from 'antd';
import style from './index.styl'
const SubMenu = Menu.SubMenu;

class Sider extends React.Component {
  state = {
    current: '/sub1/1',
    openKeys: ['/sub1'],
  }
  menu = [
    {
      key:'/sub1',
      title:<span><Icon type="mail" /><span>Navigation One</span></span>,
      children:[
        {
          key:'/sub1/1',
          title:'Option 1',
        },
        {
          key:'/sub1/2',
          title:'Option 2',
        },
      ],
    }
  ]
  handleClick = (e) => {
    console.log('Clicked: ', e);
    this.setState({ current: e.key });
  }
  onOpenChange = (openKeys) => {
    const state = this.state;
    const latestOpenKey = openKeys.find(key => !(state.openKeys.indexOf(key) > -1));
    const latestCloseKey = state.openKeys.find(key => !(openKeys.indexOf(key) > -1));

    let nextOpenKeys = [];
    if (latestOpenKey) {
      nextOpenKeys = this.getAncestorKeys(latestOpenKey).concat(latestOpenKey);
    }
    if (latestCloseKey) {
      nextOpenKeys = this.getAncestorKeys(latestCloseKey);
    }
    this.setState({ openKeys: nextOpenKeys });
  }
  getAncestorKeys = (key) => {
    const map = {
      sub3: ['sub2'],
    };
    return map[key] || [];
  }
  render() {
    return (
      <Menu
        mode="inline"
        openKeys={this.state.openKeys}
        selectedKeys={[this.state.current]}
        style={{ width: 240 }}
        onOpenChange={this.onOpenChange}
        onClick={this.handleClick}
      >
      {
        this.menu.map((item)=>{
          var menuItem = item.children.map((subItem)=>{
            return <Menu.Item key={subItem.key}>{subItem.title}</Menu.Item>
          })
          return <SubMenu key={item.key} title={item.title}>{menuItem}</SubMenu>
        })
      }
      </Menu>
    );
  }
}
var App = CSSModules(Sider, style);

ReactDOM.render(<App />, document.getElementById('app'));