最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Update table content on selecting tabs - Stack Overflow

programmeradmin0浏览0评论

I have a table that the content need to be filtered by status tabs ('new', 'on process', 'delivered', etc) usually i'm using useEffect to catch this status tabs selection, and useState to update the table data, but now i have issues where the state is updating (by logging the 'tableData' content just after i call setTableData) but the table still on previous 'tableData' state.. can you guys tell me where is the problem?

export const OrdersTab = (tabsData : any) => {
// console.log(tabsData);
const [activeTab, setActiveTab] : any = useState(null);
const [activeStatusTab, setActiveStatusTab] : any = useState();
const [tableData, setTableData]:any[] = useState([]);
const [loading, setLoading] = useState(false);

// console.log(tabsData);

useEffect(() => {
    
        if (activeStatusTab) {
            let filteredOrderes = tabsData.initTableData;
            // console.log(filteredOrderes);
            if (activeStatusTab == 'all') {
                filteredOrderes = tabsData.initTableData;
            } else {
                filteredOrderes = filteredOrderes.filter((orders:any) => 
                    orders.status.toString().toLowerCase().includes(activeStatusTab.toLowerCase())
                );
            }
            // console.log(filteredOrderes.length);
            setTableData(filteredOrderes);
            console.log(tableData.length); /* <<-- checking if state updating/not */
        }
}, [activeStatusTab]);

let statusTabs = [
    {
      id: "all",
      label: "All"
    },
    {
      id: "new",
      label: "New"
    },
    {
      id: "process",
      label: "On Process"
    },
    {
      id: "delivery",
      label: "Delivery"
    },
    {
      id: "completed",
      label: "Completed"
    },
    {
      id: "canceled",
      label: "Canceled"
    },
    {
      id: "failed",
      label: "Failed"
    },
];
return (
    <Card>
        <CardBody>
            <div className="flex w-full flex-col">
                <Tabs aria-label="Dynamic tabs" 
                    onSelectionChange={(tabKey) => setActiveTab(tabKey)}
                    fullWidth={true} 
                    items={tabsData.tabsData} >
                    {(item:any) => (
                    <Tab key={item.id} title={item.name}>
                        <Tabs aria-label="Options" onSelectionChange={(statusKey) => setActiveStatusTab(statusKey)} fullWidth={true} items={statusTabs}>
                            {(item) => (
                            <Tab key={item.id} title={item.label}>
                                    <Table id="tablexxx" aria-label="Example empty table">
                                        <TableHeader>
                                            <TableColumn>Product(s)</TableColumn>
                                            <TableColumn>Date</TableColumn>
                                            <TableColumn>Store</TableColumn>
                                            <TableColumn>Status</TableColumn>
                                            <TableColumn>Total Amount</TableColumn>
                                            <TableColumn>Courier</TableColumn>
                                            <TableColumn>Action</TableColumn>
                                        </TableHeader>
                                        {(tableData.length > 0) ? (
                                            <TableBody>
                                                {tableData.map((item:any) => (
                                                    <TableRow key={item.invoice}>
                                                        <TableCell>
                                                            <Link href={'/orders/' + item.id}>
                                                                {item.products[0].main_product.name}
                                                                <p className="text-default-400">SKU: {item.products[0].main_product.sku} x {item.products[0].qty}</p>
                                                                <p className="text-default-400">Invoice: {item.invoice}</p>
                                                            </Link>
                                                        </TableCell>
                                                        <TableCell>{item.createdAt.split('T')[0]}</TableCell>
                                                        <TableCell>{item.store.name}</TableCell>
                                                        <TableCell>{item.status}</TableCell>
                                                        <TableCell>{item.total_amount}</TableCell>
                                                        <TableCell>{item.logistic.name}</TableCell>
                                                        <TableCell>
                                                            {<Dropdown>
                                                                <DropdownTrigger>
                                                                    <Button 
                                                                    variant="bordered"
                                                                    isIconOnly  
                                                                    >
                                                                        <svg className="bi bi-three-dots-vertical" fill="currentColor" height="16" viewBox="0 0 16 16" width="16" xmlns=";><path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>
                                                                    </Button>
                                                                </DropdownTrigger>
                                                                <DropdownMenu aria-label="Static Actions">
                                                                    <DropdownItem key="new">View</DropdownItem>
                                                                    <DropdownItem key="copy"><Link href={"/orders/" + item.id}>Process</Link></DropdownItem>
                                                                    <DropdownItem key="delete" className="text-danger" color="danger">
                                                                    Reject
                                                                    </DropdownItem>
                                                                </DropdownMenu>
                                                            </Dropdown>}
                                                        </TableCell>
                                                    </TableRow>
                                                ))}
                                            </TableBody>
                                        ) : (
                                            <TableBody emptyContent={"No rows to display."}>{[]}</TableBody>
                                        )} 
                                        
                                    </Table>
                            </Tab>
                            )}
                        </Tabs>
                    </Tab>
                    )}
                    
                </Tabs>
            </div>  
        </CardBody>
    </Card>
)}

I have a table that the content need to be filtered by status tabs ('new', 'on process', 'delivered', etc) usually i'm using useEffect to catch this status tabs selection, and useState to update the table data, but now i have issues where the state is updating (by logging the 'tableData' content just after i call setTableData) but the table still on previous 'tableData' state.. can you guys tell me where is the problem?

export const OrdersTab = (tabsData : any) => {
// console.log(tabsData);
const [activeTab, setActiveTab] : any = useState(null);
const [activeStatusTab, setActiveStatusTab] : any = useState();
const [tableData, setTableData]:any[] = useState([]);
const [loading, setLoading] = useState(false);

// console.log(tabsData);

useEffect(() => {
    
        if (activeStatusTab) {
            let filteredOrderes = tabsData.initTableData;
            // console.log(filteredOrderes);
            if (activeStatusTab == 'all') {
                filteredOrderes = tabsData.initTableData;
            } else {
                filteredOrderes = filteredOrderes.filter((orders:any) => 
                    orders.status.toString().toLowerCase().includes(activeStatusTab.toLowerCase())
                );
            }
            // console.log(filteredOrderes.length);
            setTableData(filteredOrderes);
            console.log(tableData.length); /* <<-- checking if state updating/not */
        }
}, [activeStatusTab]);

let statusTabs = [
    {
      id: "all",
      label: "All"
    },
    {
      id: "new",
      label: "New"
    },
    {
      id: "process",
      label: "On Process"
    },
    {
      id: "delivery",
      label: "Delivery"
    },
    {
      id: "completed",
      label: "Completed"
    },
    {
      id: "canceled",
      label: "Canceled"
    },
    {
      id: "failed",
      label: "Failed"
    },
];
return (
    <Card>
        <CardBody>
            <div className="flex w-full flex-col">
                <Tabs aria-label="Dynamic tabs" 
                    onSelectionChange={(tabKey) => setActiveTab(tabKey)}
                    fullWidth={true} 
                    items={tabsData.tabsData} >
                    {(item:any) => (
                    <Tab key={item.id} title={item.name}>
                        <Tabs aria-label="Options" onSelectionChange={(statusKey) => setActiveStatusTab(statusKey)} fullWidth={true} items={statusTabs}>
                            {(item) => (
                            <Tab key={item.id} title={item.label}>
                                    <Table id="tablexxx" aria-label="Example empty table">
                                        <TableHeader>
                                            <TableColumn>Product(s)</TableColumn>
                                            <TableColumn>Date</TableColumn>
                                            <TableColumn>Store</TableColumn>
                                            <TableColumn>Status</TableColumn>
                                            <TableColumn>Total Amount</TableColumn>
                                            <TableColumn>Courier</TableColumn>
                                            <TableColumn>Action</TableColumn>
                                        </TableHeader>
                                        {(tableData.length > 0) ? (
                                            <TableBody>
                                                {tableData.map((item:any) => (
                                                    <TableRow key={item.invoice}>
                                                        <TableCell>
                                                            <Link href={'/orders/' + item.id}>
                                                                {item.products[0].main_product.name}
                                                                <p className="text-default-400">SKU: {item.products[0].main_product.sku} x {item.products[0].qty}</p>
                                                                <p className="text-default-400">Invoice: {item.invoice}</p>
                                                            </Link>
                                                        </TableCell>
                                                        <TableCell>{item.createdAt.split('T')[0]}</TableCell>
                                                        <TableCell>{item.store.name}</TableCell>
                                                        <TableCell>{item.status}</TableCell>
                                                        <TableCell>{item.total_amount}</TableCell>
                                                        <TableCell>{item.logistic.name}</TableCell>
                                                        <TableCell>
                                                            {<Dropdown>
                                                                <DropdownTrigger>
                                                                    <Button 
                                                                    variant="bordered"
                                                                    isIconOnly  
                                                                    >
                                                                        <svg className="bi bi-three-dots-vertical" fill="currentColor" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3./2000/svg"><path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>
                                                                    </Button>
                                                                </DropdownTrigger>
                                                                <DropdownMenu aria-label="Static Actions">
                                                                    <DropdownItem key="new">View</DropdownItem>
                                                                    <DropdownItem key="copy"><Link href={"/orders/" + item.id}>Process</Link></DropdownItem>
                                                                    <DropdownItem key="delete" className="text-danger" color="danger">
                                                                    Reject
                                                                    </DropdownItem>
                                                                </DropdownMenu>
                                                            </Dropdown>}
                                                        </TableCell>
                                                    </TableRow>
                                                ))}
                                            </TableBody>
                                        ) : (
                                            <TableBody emptyContent={"No rows to display."}>{[]}</TableBody>
                                        )} 
                                        
                                    </Table>
                            </Tab>
                            )}
                        </Tabs>
                    </Tab>
                    )}
                    
                </Tabs>
            </div>  
        </CardBody>
    </Card>
)}
Share Improve this question edited Nov 20, 2024 at 7:23 DarkBee 15.5k8 gold badges72 silver badges117 bronze badges asked Nov 20, 2024 at 3:52 didiadas29didiadas29 421 silver badge10 bronze badges 1
  • nevermind, i already fixed this issue.. if anyone has same problem, comment here if you need my solutions – didiadas29 Commented Nov 20, 2024 at 8:36
Add a comment  | 

1 Answer 1

Reset to default -1

Issue: setTableData(filteredOrderes) is called, but React updates the state asynchronously. So, console.log(tableData.length) right after setTableData is still showing the old value of tableData since the state update hasn't been applied yet.

Fix:

  1. Remove the console.log(tableData.length) from directly after setTableData.
  2. Add a separate useEffect that runs when tableData changes and log its value there.

<script src="https://cdnjs.cloudflare/ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare/ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
import { useEffect, useState } from 'react';

export const OrdersTab = (tabsData: any) => {
  const [activeTab, setActiveTab] = useState(null);
  const [activeStatusTab, setActiveStatusTab] = useState();
  const [tableData, setTableData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);

  // Effect to filter table data based on selected status tab
  useEffect(() => {
    if (activeStatusTab) {
      let filteredOrders = tabsData.initTableData;
      
      if (activeStatusTab === 'all') {
        filteredOrders = tabsData.initTableData;
      } else {
        filteredOrders = filteredOrders.filter((orders: any) => 
          orders.status.toString().toLowerCase().includes(activeStatusTab.toLowerCase())
        );
      }

      // Update tableData state with filtered orders
      setTableData(filteredOrders);
    }
  }, [activeStatusTab, tabsData.initTableData]);

  // Effect to log the updated tableData when it changes
  useEffect(() => {
    console.log('Updated tableData length:', tableData.length);
  }, [tableData]); // This effect runs whenever tableData is updated

  let statusTabs = [
    { id: "all", label: "All" },
    { id: "new", label: "New" },
    { id: "process", label: "On Process" },
    { id: "delivery", label: "Delivery" },
    { id: "completed", label: "Completed" },
    { id: "canceled", label: "Canceled" },
    { id: "failed", label: "Failed" },
  ];

  return (
    <Card>
      <CardBody>
        <div className="flex w-full flex-col">
          <Tabs
            aria-label="Dynamic tabs"
            onSelectionChange={(tabKey) => setActiveTab(tabKey)}
            fullWidth={true}
            items={tabsData.tabsData}
          >
            {(item: any) => (
              <Tab key={item.id} title={item.name}>
                <Tabs
                  aria-label="Options"
                  onSelectionChange={(statusKey) => setActiveStatusTab(statusKey)}
                  fullWidth={true}
                  items={statusTabs}
                >
                  {(item) => (
                    <Tab key={item.id} title={item.label}>
                      <Table id="tablexxx" aria-label="Example empty table">
                        <TableHeader>
                          <TableColumn>Product(s)</TableColumn>
                          <TableColumn>Date</TableColumn>
                          <TableColumn>Store</TableColumn>
                          <TableColumn>Status</TableColumn>
                          <TableColumn>Total Amount</TableColumn>
                          <TableColumn>Courier</TableColumn>
                          <TableColumn>Action</TableColumn>
                        </TableHeader>
                        {tableData.length > 0 ? (
                          <TableBody>
                            {tableData.map((item: any) => (
                              <TableRow key={item.invoice}>
                                <TableCell>
                                  <Link href={'/orders/' + item.id}>
                                    {item.products[0].main_product.name}
                                    <p className="text-default-400">
                                      SKU: {item.products[0].main_product.sku} x {item.products[0].qty}
                                    </p>
                                    <p className="text-default-400">Invoice: {item.invoice}</p>
                                  </Link>
                                </TableCell>
                                <TableCell>{item.createdAt.split('T')[0]}</TableCell>
                                <TableCell>{item.store.name}</TableCell>
                                <TableCell>{item.status}</TableCell>
                                <TableCell>{item.total_amount}</TableCell>
                                <TableCell>{item.logistic.name}</TableCell>
                                <TableCell>
                                  <Dropdown>
                                    <DropdownTrigger>
                                      <Button variant="bordered" isIconOnly>
                                        <svg
                                          className="bi bi-three-dots-vertical"
                                          fill="currentColor"
                                          height="16"
                                          viewBox="0 0 16 16"
                                          width="16"
                                          xmlns="http://www.w3./2000/svg"
                                        >
                                          <path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z" />
                                        </svg>
                                      </Button>
                                    </DropdownTrigger>
                                    <DropdownMenu aria-label="Static Actions">
                                      <DropdownItem key="new">View</DropdownItem>
                                      <DropdownItem key="copy">
                                        <Link href={"/orders/" + item.id}>Process</Link>
                                      </DropdownItem>
                                      <DropdownItem key="delete" className="text-danger" color="danger">
                                        Reject
                                      </DropdownItem>
                                    </DropdownMenu>
                                  </Dropdown>
                                </TableCell>
                              </TableRow>
                            ))}
                          </TableBody>
                        ) : (
                          <TableBody emptyContent={"No rows to display."}>{[]}</TableBody>
                        )}
                      </Table>
                    </Tab>
                  )}
                </Tabs>
              </Tab>
            )}
          </Tabs>
        </div>
      </CardBody>
    </Card>
  );
};

发布评论

评论列表(0)

  1. 暂无评论