首页 > 解决方案 > jsx中的条件和数组的映射

问题描述

您好,我有以下方案来呈现我的菜单和下拉菜单:

const MenuBar = props => {
  const MenuTags = [
    {
      name: 'home',
      redirectTo: '/',
      dropdown: {
        items: ['one', 'two', 'three'],
      },
    },
    {
      name: 'about',
      redirectTo: '../about',
      dropdown: {
        items: ['one', 'two', 'three'],
      },
    },
    { name: 'not dropdown', redirectTo: '../dashboard' },
    { name: 'not dropdown', redirectTo: '../dashboard/about' },
  ];
  const [visibleMenu, setVisibleMenu] = useState(
      MenuTags.reduce((r, e) => ((r[e.name] = false), r), {}),
    ),
    onUpdateVisibility = item => {
      const visibleMenuCopy = { ...visibleMenu };
      Object.keys(visibleMenuCopy).forEach(
        key => (visibleMenuCopy[key] = key == item),
      );
      setVisibleMenu(visibleMenuCopy);
    };
  console.log(visibleMenu);
  return (
    <NavUl isOpen={props.isOpen}>
      {MenuTags.map(item => (
        <MenuItem
          options={item}
          visibleMenu={visibleMenu}
          onClick={() => onUpdateVisibility(item)}
        />
      ))}
      <li>
        <FontAwesomeIcon
          onClick={() => props.setOpenBox(!props.isOpen)}
          className="searchIcon"
          rotation={90}
          icon={faSearch}
          size="1x"
          fixedWidth
          color="rgba(0, 0, 0, 0.08);"
        />
      </li>
    </NavUl>
  );
};

基本上在这里我有一个数组,其中我有将在我的 li 中呈现的名称以及 redirectLink (用于反应路由器链接)

const MenuItem = props => {
  const { name, redirectTo, dropdown } = props.options;
  return (
    <NavLi>
      <Link to={redirectTo}>{name}</Link>
      {dropdown && dropdown !== null ? <DropDown {...props} /> : ''}
    </NavLi>
  );
};

在这里,我基本上呈现我的菜单项读取,如果下拉变量为真,我将呈现以下组件:

const DropDown = props => {
  const { items } = props;
  console.log(props.visibleMenu);
  return(
    <>
    { items && items !== null && props.visibleMenu ?

    }
    </>
  )
};

因此,在这里我将检查 jsx 中的一些条件,并使用我的 items 数组中的 .map 来呈现以下组件:

<ul>
<li>
<a>
</li>
</ul>

对于数组中的每个项目好吧我不知道我的代码是好还是奇怪如果有人可以帮助我以及如何改进代码

标签: reactjs

解决方案


您的代码是一个很好的尝试,但是您正在做一些奇怪的事情。而不是使用一个类来处理所有事情,而是利用每次反应如何呈现状态。你不需要这么多课程。这里以这件作品为例:

const [visibleMenu, setVisibleMenu] = useState(
      MenuTags.reduce((r, e) => ((r[e.name] = false), r), {}),
    ),
    onUpdateVisibility = item => {
      const visibleMenuCopy = { ...visibleMenu };
      Object.keys(visibleMenuCopy).forEach(
        key => (visibleMenuCopy[key] = key == item),
      );
      setVisibleMenu(visibleMenuCopy);
    };

阅读起来非常混乱,如果我的一位开发人员向我提出拉取请求,我会拒绝它。就像我说的利用渲染反应了。另一件事是利用一个独立的部分 MenuBar 不需要知道 dropdownItems 是可见的还是不可见的。链接也可以重命名:)

// No need for a class here an array will work great!
const menuTags = [
  { name: 'home', link: '/', dropdownItems: ['one', 'two', 'three'] },
  // ... other menu tags you had.
]

const MenuBar = props => {
  return (
    <NavUl isOpen={props.isOpen}>
      {menuTags.map(menuTag => <MenuTag tag={menuTag} />)
      <li>
        <FontAwesomeIcon
          // Move the logic to only be in the Parent, this component shouldn't have to
          // pass it's parents variables.
          onClick={props.toggleOpen}
          // ... the rest of what you had
        />
      </li>
    </NavUl >
  )
}

现在,清理了更多逻辑的那部分可以移动到 MenuItem 本身。此外,您实际上并不需要可以在 MenuItem 中处理的 DropDown 文件。我注意到你也这样做if (dropdown && dropdown !== null)if (dropdown)。如果变量为 null,则在 javascript 中为 false。另一件事是,如果你想在 react if 语句上渲染一些东西,? <Dropdown /> : ''你可以这样做&& <Dropdown />

const MenuItem = ({ tag }) => {
  const { name, link, dropdownItems } = tag;
  // Dropdown visibility can be handled here.
  const [visibility, setVisibility] = useState(false)

  return (
    <NavLi onClick={() => setVisibility(!visibility)} >
      <Link to={link}>{name}</Link>
      // If these are true dropdown items will appear.
      {visibility && dropdownItem && (
        {dropdownItems.map(item => (
          <ul>
            <li>
              <a>{item}</a>
            </li>
          </ul>
        ))}
      )}
    </NavLi>
  );
};

那应该是你所追求的。


推荐阅读