【问题标题】:React material-ui Menu: how to dynamically fill nested menus?React material-ui Menu:如何动态填充嵌套菜单?
【发布时间】:2018-09-20 05:14:22
【问题描述】:

我想从一组值中动态填充 MenuItem (https://www.material-ui.com/#/components/menu) 的“menuItems”属性。 我发现了几篇关于使用映射语法的帖子,实际上我设法使它能够用 MenuItem 元素填充菜单。但是我没有设法让它填充 menuItems 数组(嵌套菜单)。

感谢任何帮助,我是 react 和 javascript 的新手,所以很可能我遗漏了一些明显的东西。 谢谢

这是我写的:

class PopupMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = { menu: props.menu, key: (props.menu.id + "_menu"), open: false, actions: null};
  }

  
...
  
  async createActionOrMenu(actionOrMenu) {
	  if (actionOrMenu[1] == true) {
		  // submenu
		  let menu = actionOrMenu[0];
		  let actionsOrMenus = await window.epic.content(menu);
		  return <MenuItem 
			  primaryText={label(menu.title)} 
			  menuItems={actionsOrMenus.map(this.createActionOrMenu.bind(this))} // the line I have problem with
		  />
	  } else {
		  //action
		  let action = actionOrMenu[0];
		  return <MenuAction action={action}/>
	  }
  }
  
  createActions(actionsOrMenus) {
	  if (!actionsOrMenus || actionsOrMenus.length === 0) {
		  return;
	  }
	  return actionsOrMenus.map(this.createActionOrMenu.bind(this)); // the map syntax to dynamically fill elements: works like charm
  }

  render() {
    return (
      <div>
        <FlatButton
		  className="menubar_menu"
          onClick={this.handleClick}
          label={label(this.state.menu.title)}
		  hoverColor="lightgrey"
		  primary = {this.state.open}
        />
        <Popover
          open={this.state.open}
          anchorEl={this.state.anchorEl}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          onRequestClose={this.handleRequestClose}
        >				  
          <Menu key= {this.state.key+"popup"}>
		        {this.createActions(this.state.actions)}
          </Menu>
        </Popover>
      </div>
    );
  }
}

【问题讨论】:

  • 这里是控制台输出:警告:失败的道具类型:无效的道具menuItems 提供给MenuItem,需要一个 ReactNode。在菜单项中
  • 看来我的问题是 createActionOrMenu 的 async 关键字。该函数返回一个 Promise 而不是 jsx 数组

标签: dynamic menu material-ui


【解决方案1】:

这是一个工作代码: 我必须解决的第一个问题是我的“异步”关键字,请参阅 cmets。 然后这条线起作用: menuItems={createActions(this.state.actions)}

class MenuAction extends React.Component {
	constructor(props) {
		super(props);
		this.state = {action: props.action};
	}
	
	render () {
		return (
			<MenuItem primaryText={label(this.state.action.text)}/>
		);
	}
}

function createActionOrMenu(actionOrMenu) {
  if (!actionOrMenu || !actionOrMenu[0]) {
		console.error("invalid action/menu sent to createActionOrMenu");
		return;
	}
  if (actionOrMenu[1] == true) {
	  // submenu
	  return <SubMenu menu= {actionOrMenu[0]} key = {actionOrMenu[0].id + "_submenu"} />
  } else {
	  // action
	  return <MenuAction action= {actionOrMenu[0]} key = {actionOrMenu[0].id + "_action"}/>
  }
}

function createActions(actionsOrMenus) {
	if (!actionsOrMenus || actionsOrMenus.length === 0) {
		return;
	}
	return actionsOrMenus.map(createActionOrMenu);
}
  
  

class SubMenu extends React.Component {
	constructor(props) {
		super(props);
		this.state = { menu: props.menu, actions: []};
	}
	
	UNSAFE_componentWillMount() {
	  this.init();
	}
  
	async init() {
		let content = await window.epic.currentPage.menuBarSite.content(this.state.menu);
		this.setState({actions: content});  
	}	
	  
	 render() {
		 return <MenuItem 
			primaryText={label(this.state.menu.title)} 
			key={this.state.menu.title}
			menuItems={createActions(this.state.actions)}  // this works
		  />
	 }
}

class PopupMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {menu: props.menu, actions: [], open: false};
  }

  UNSAFE_componentWillMount() {
	  this.init();
  }
  
  async init() {
	  let content = await window.epic.currentPage.menuBarSite.content(this.state.menu);
	  this.setState({actions: content});  
  }
  
  handleClick = (event) => {
    // This prevents ghost click.
    event.preventDefault();

    this.setState({
      open: true,
      anchorEl: event.currentTarget,
    });
  };

  handleRequestClose = () => {
    this.setState({
      open: false,
    });
  };
  

  render() {
    return (
      <div>
        <FlatButton
		  className="menubar_menu"
          onClick={this.handleClick}
          label={label(this.state.menu.title)}
		  hoverColor="lightgrey"
		  primary = {this.state.open}
        />
        <Popover
          open={this.state.open}
          anchorEl={this.state.anchorEl}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          onRequestClose={this.handleRequestClose}
        >				  
          <Menu key= {this.state.key+"_popup"}>
		    {createActions(this.state.actions)}
          </Menu>
        </Popover>
      </div>
    );
  }
}

【讨论】:

    猜你喜欢
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    相关资源
    最近更新 更多