Reactjs 如何使用typescript和react根据所选选项卡显示来自对象的相关信息?

Reactjs 如何使用typescript和react根据所选选项卡显示来自对象的相关信息?,reactjs,typescript,Reactjs,Typescript,我的数据结构(对象)如下所示 const Items = { id: '1', Orders: [ { id: '2', title: 'Order1', } { id: '3', title: 'Order2', } ], subItems: [ { id: '1

我的数据结构(对象)如下所示

const Items = {
    id: '1',
    Orders: [
        {
            id: '2',
            title: 'Order1',
        }
        {
            id: '3',
            title: 'Order2',
        }
    ],
    subItems: [
        { 
            id: '1',
            Orders: [
                {
                    id: '1',
                    title: 'subitem1-order1',
                    status: 'new',
                }
                {
                    id: '2',
                    title: 'subitem1-order2',
                    status: 'done',
                }
            ],
        }
        { 
            id: '2',
            Orders: [
                {
                    id: '1',
                    title: 'subitem2-order1',
                    status: 'new',
                }
                {
                    id: '2',
                    title: 'subitem2-order2',
                    status: 'done',
                }
            ],
        }
    ]
}
从上面的数据可以看出,items对象具有多个订单的订单和子项

我有两个标签。订单和子项订单。当用户单击Orders选项卡时,我应该只列出Items对象的订单,因此结果应该是

订单1和订单2

同样,当用户单击选项卡子项Orders时,结果应为

子项1-order1、子项1-order2、子项2-order1和子项2-order2

还有一些筛选器div,如all、new、done和accepted。它默认为all,意味着将显示所有新的、完成的或接受的状态顺序。 如果用户单击“筛选新订单”,则会列出状态为“新建”的订单(订单和子项订单) 如果用户单击filter done,它将列出状态为done的订单(订单和子项订单) 如果用户单击“过滤器已接受”,则会列出状态为“已接受”的订单(订单和子项订单)

下面是我的代码,它当前将订单和子项订单作为对象数组,并按创建顺序将它们列在一起。我已经添加了一些还不起作用的选项卡

export enum TabOptions {
    Orders = 'Orders',
    SubItemOrders = 'SubItemOrders',
}

function getAllOrders(items) {
    return [
        ...(items.Orders || []),
        ...(items.subItems
        ? items.subItems.reduce((acc: any, subItem) => {
            return [...acc, ...(subItem.Orders || [])];
        }, [])
          : []),
    ];
}

export const useOrdersByFilter = (items) => {
    return React.useMemo(() => {
        const Orders = getAllOrders(items); //this groups all orders and subitem orders into one array of objects

        const sortedOrders = orderBy(Orders,
            ({ startDate }) => new Date(startDate),
            ['asc']
        );

        const delayedOrders = sortedOrders.filter(o => {
            const now = moment();
            const end = moment(o.endDate);
            const isDelayed =
                o.status !== OrderStatus.DONE && end.isBefore(now, 'day');
            return isDelayed;
        });

        const byStatus = groupBy(sortedOrders, 'status');

        return {
            [OrderFilter.ALL]: sortedOrders,
            [OrderFilter.COMPLETE]: byStatus[OrderStatus.DONE] || [],
            [OrderFilter.DELAYED]: delayedOrders,
        };
    }, [item]);
};


function Parent () {
    const items; //this has value as the items data structure that i mentioned above.
    const [selectedTab, setSelectedTab] = React.useState(TabOptions.Orders);//this             keeps track of tab that user clicked.defaulted to Orders tab.
    const [activeFilter, setActiveFilter] = React.useState<OrderFilter>(
        OrderFilter.ALL
    ); //this keeps track of filter type that user selected. default to all.


    const OrdersByFilter = useOrdersByFilter(items);
    const allOrders = OrdersByFilter[OrderFilter.ALL] || [];

    return (
        <Wrapper>
            <Content>
                <span> title</span>
                <Tabs>
                    <Tab
                        onClick={() => setSelectedTab(TabOptions.Orders)}
                        className={selectedTab === TabOptions.Orders ? 'active' : ''}
                    >
                        <span>Orders</span>
                    </Tab>
                    <Tab
                        onClick={() => setSelectedTab(TabOptions.SubItemOrders)}
                        className={selectedTab === TabOptions.SubItemOrders ?             'active' : ''}
                    >
                        <span>subItem-Orders</span>
                    </Tab>
                </Tabs>
                {allOrders.length > 0 &&
                    <OrderFilters //this component displays the filter bars based on  the orders  that have been added recently. if there is new Order added by user of status say 'done' then it adds filter for done. similarly for others too.
                        activeFilter={activeFilter}
                        onFilterChange={setActiveFilter}
                        Orders={allOrders}
                    </OrderFilter>
                }

                <OrdersWrapper> //this is the one that lists the orders (both the orders and subitem-orders in the same list
                    <OrderList Orders={OrdersByFilter[activeFilter]} /> 
                </OrdersWrapper>
            </Content>
        </Wrapper>
    );
}
  

    
//the OrderList component lists the orders (both the orders and subitemorders)

function OrderList({Orders}:Props) {
    return (
        {item.data.map(o => {
            return (
              <OrderCardWrapper key={o.id}>
                <OrderCard data={o} /> //this is  div that displays order info.
              </OrderCardWrapper>
            );
          })}
      );
 }
导出枚举选项卡选项{
订单='订单',
SubItemOrders='SubItemOrders',
}
函数getAllOrders(项){
返回[
…(items.Orders | |[]),
…(项。子项)
?项目。子项目。减少((附件:任何,子项目)=>{
返回[…acc,…(subItem.Orders | |[])];
}, [])
: []),
];
}
导出常量useOrdersByFilter=(项)=>{
返回React.useMoom(()=>{
const Orders=getAllOrders(items);//将所有订单和子项订单分组到一个对象数组中
const sortedOrders=orderBy(订单,
({startDate})=>新日期(startDate),
['asc']
);
const delayedOrders=sortedOrders.filter(o=>{
const now=力矩();
常数结束=力矩(o.endDate);
常数延迟=
o、 状态!==OrderStatus.DONE&&end.isBefore(现在是“天”);
返回延迟;
});
const byStatus=groupBy(分拣机,“状态”);
返回{
[OrderFilter.ALL]:分拣机,
[OrderFilter.COMPLETE]:byStatus[OrderStatus.DONE]| |[],
[OrderFilter.DELAYED]:delayedOrders,
};
},[项目];
};
函数父级(){
const items;//它的值与我前面提到的items数据结构相同。
const[selectedTab,setSelectedTab]=React.useState(TabOptions.Orders);//这会跟踪用户单击的选项卡。默认为Orders选项卡。
常量[activeFilter,setActiveFilter]=React.useState(
OrderFilter.ALL
);//这将跟踪用户选择的筛选器类型。默认为all。
const OrdersByFilter=useOrdersByFilter(项目);
常量allOrders=OrdersByFilter[OrderFilter.ALL]| |[];
返回(
标题
setSelectedTab(TabOptions.Orders)}
className={selectedTab==TabOptions.Orders?'active':''}
>
命令
setSelectedTab(TabOptions.SubItemOrders)}
className={selectedTab==TabOptions.SubItemOrders?'active':''}
>
分项订单
{allOrders.length>0&&
{
返回(
//这是显示订单信息的div。
);
})}
);
}
上述代码在一个列表中同时显示订单和子项订单。但现在我想把它们分成几个部分。当用户选择“订单”选项卡时,只应看到订单。当用户单击“子项订单”选项卡时,只应看到子项订单


如何修复上述代码。有人能帮我吗。谢谢。

一个可能的解决方案,我将只在此处输入相关代码:

首先将getAllOrder拆分为2个函数 (由于reduce已经生成了一个浅拷贝,您可以删除…运算符)

将getAllOrder调用移动到父函数,以便能够为每个项目(订单和子订单)调用它

当然,现在useOrdersByFilter接受订单而不是项目

export const useOrdersByFilter = (Orders) => {
    return React.useMemo(() => {

        const sortedOrders = orderBy(Orders,
        ...
回到父函数,应根据用户选择(项或子项)初始化Allorder:


非常感谢。这正如预期的那样有效。除了我也为getAllSubOrders添加了…运算符。否则它将给出数组的数组。当更改选项卡选择时,列表中的更改也会出现一些闪烁。你知道是什么引起的吗?谢谢,谢谢!我很乐意帮忙。闪烁是可见的,我怀疑性能问题,可能是由于项目初始化(将console.log放入useMemo回调以查看是否调用了多次),可能像OrderList这样的子组件在重新渲染时会变慢(逐个删除以查看闪烁是否消失)
function Parent() {
    ...       
    const Orders = getAllOrders(items);
    const SubOrders = getAllSubOrders(items);
    const OrdersByFilter = useOrdersByFilter(Orders);
    const SubOrdersByFilter = useOrdersByFilter(SubOrders);
export const useOrdersByFilter = (Orders) => {
    return React.useMemo(() => {

        const sortedOrders = orderBy(Orders,
        ...
    const allOrders = (selectedTab === TabOptions.SubItemOrders ? SubOrdersByFilter[OrderFilter.ALL] : OrdersByFilter[OrderFilter.ALL]) || [];