控制显示哪个组件的重构代码

Refactoring code that controls which component gets displayed

嘿,我正在做一个项目,当用户点击一个按钮时,我需要显示不同的组件。你能看看我是否可以将代码反应得更干净吗?我在前端使用 react/next.js。

正在设置 useState 以控制查看哪个组件。使用布尔数组作为输入

const [views, setViews] = useState([true, false, false])

显示用户将单击以select查看的按钮

<nav className='flex flex-row justify-end'>
   <button
      type='button'
      className={`mainBtn p-2 mr-2` + (views[0] ? ' active' : '')}
      onClick={() => setViews([true, false, false])}
   >Create New Order</button>
   <button
      type='button'
      className={`mainBtn p-2 mr-2` + (views[1] ? ' active' : '')}
      onClick={() => setViews([false, true, false]) }
   >View orders</button>
   <button
      type='button'
      className={`mainBtn p-2 mr-2` + (views[2] ? ' active' : '')} 
      onClick={() => setViews([false, false, true]) }
   >Manage account</button>
   <button 
      type='button'
      className={`mainBtn p-2 mr-2`}
      onClick={() => signOut() }
   >Sign Out</button>
</nav>

使用条件渲染显示所需组件

{views[0] && <DisplayCreateNewOrder id={session.user.customer.locationID}/>}
{views[1] && <DisplayPendingOrders id={session.user.customer.locationID}/>}
{views[2] && <DisplayAccount customer={session.user.customer}/>}

非常感谢任何反馈。此外,最后两个代码块被包裹在一个 div 元素中,带有一些顺风 类.

谢谢

首先,从您的代码可以明显看出在任何给定时间只能出现一个视图。这意味着您可以只持有当前活动视图的 id/name 而不是持有 3 个布尔值:

const {CreateNewOrder, ViewOrders, ManageAccount} = {'create', 'view', 'account'};
const [activeView, setActiveView] = useState(CreateNewOrder);

然后你可以使用函数使条件更具可读性:

const isViewActive = view => activeView === view;

你会像这样使用它:

{isViewActive(ManageAccount) && <DisplayAccount id={session.user.customer}/>}

通过让所有三个视图都接受 customer 而不是一些仅接受 ID,您可以进行更多整合。

您可以简化状态,因为一次只有一个视图可见,不需要存储三个布尔变量。完整示例 - Codesandbox.

将视图存储在 enum/constant -

const Views = Object.freeze({
  Create: "Create",
  View: "View",
  Manage: "Manage"
});

状态可以简单的是当前活动视图,很简单-

const [view, setView] = useState(Views.View);

按钮可以重构为一个可重用的组件 -

const LinkButton = ({ text, isActive, onClick }) => {
    return (
      <button
        type="button"
        className={`mainBtn p-2 mr-2` + (isActive ? " active" : "")}
        onClick={onClick}
      >
        {text}
      </button>
    );
  };

然后用作

<LinkButton
  text="View Orders"
  isActive={view === Views.View}
  onClick={() => setView(Views.View)}
/>