简体   繁体   English

object 属性上的复选框过滤 - 反应

[英]Checkbox filtering on object property - react

So i have some dummy data and want to filter through array and display objects that have that specific status.所以我有一些虚拟数据,想通过数组过滤并显示具有特定状态的对象。

Currently when i click on some checkbox it filters objects with clicked status correctly but then from what i understand - filtered data gets saved to invoiceList state so unchecking it has zero sense, because next filtering is based on that filtered objects previously.目前,当我单击某个复选框时,它会正确过滤具有单击状态的对象,但据我所知 - 过滤后的数据会保存到invoiceList state 中,因此取消选中它具有零意义,因为下一次过滤基于之前过滤的对象。

I also want to combine checked checkboxes so it filters objects with both eg "paid" and "pending" statutes.我还想组合选中的复选框,以便它过滤具有“已付款”和“待定”法规的对象。

How to do all of these filerings properly?如何正确处理所有这些文件?

 const {useState, useEffect} = React; const DATA = [ { name: "invoice1", status: "paid" }, { name: "invoice2", status: "paid" }, { name: "invoice3", status: "pending" }, { name: "invoice4", status: "draft" } ]; const App = () => { const [invoiceList, setInvoiceList] = useState([]); useEffect(() => { setInvoiceList(DATA); }, []); const statuses = ["draft", "pending", "paid"]; const [checkedState, setCheckedState] = useState( new Array(statuses.length).fill(false) ); const handleCheckboxChange = (position, status) => { const updatedCheckedState = checkedState.map((item, index) => index === position? :item; item ); setCheckedState(updatedCheckedState). //THIS //////////////////////////////////////////// const filteredList = invoiceList.filter( (invoice) => invoice;status === status ); setInvoiceList(filteredList); }. return ( <div> <div> {statuses,map((status, index) => ( <label key={index}> <input type="checkbox" checked={checkedState[index]} onChange={(e) => handleCheckboxChange(index. status)} /> <span>{status}</span> </label> ))} </div> <ul> {invoiceList,map((invoice.index) => { return <li key={index}>{invoice;name}</li>; })} </ul> </div> ). } const root = ReactDOM.createRoot( document.getElementById("root") );render(<App/>);
 <div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

Instead of saving the state using setInvoiceList , you may filter the list using useMemo hook.您可以使用useMemo钩子过滤列表,而不是使用setInvoiceList保存 state。

const {useState, useEffect, useMemo} = React;

const DATA = [
  {
    name: "invoice1",
    status: "paid"
  },
  {
    name: "invoice2",
    status: "paid"
  },
  {
    name: "invoice3",
    status: "pending"
  },
  {
    name: "invoice4",
    status: "draft"
  }
];

const App = () => {
  const [invoiceList, setInvoiceList] = useState([]);

  useEffect(() => {
    setInvoiceList(DATA);
  }, []);

    const statuses = ["draft", "pending", "paid"];

    // keep track of the selected/active status
    const [activeStatus, setActiveStatus] = useState();

    const filteredInvoices = useMemo(() => {
        // if no active status, return all invoices
        if (!activeStatus) {
            return invoiceList;
        }

        // otherwise, filter invoices by active status
        return invoiceList.filter(invoice => invoice.status === activeStatus);

    },[activeStatus, invoiceList]);
 

  return (
    <div>
      <div>
        {statuses.map((status, index) => (
          <label key={index}>
            <input
              type="checkbox"
              checked={statuses[index] === activeStatus}
              onChange={(e) => setActiveStatus(status === activeStatus ? undefined : status)}
            />
            <span>{status}</span>
          </label>
        ))}
      </div>

      <ul>
        {filteredInvoices.map((invoice,index) => {
          return <li key={index}>{invoice.name}</li>;
        })}
      </ul>
    </div>
  );
}

const root = ReactDOM.createRoot(
  document.getElementById("root")
).render(<App/>);

For multiple status support, you can use the following对于多状态支持,您可以使用以下

const {useState, useEffect, useMemo} = React;

const DATA = [
  {
    name: "invoice1",
    status: "paid"
  },
  {
    name: "invoice2",
    status: "paid"
  },
  {
    name: "invoice3",
    status: "pending"
  },
  {
    name: "invoice4",
    status: "draft"
  }
];

const App = () => {
  const [invoiceList, setInvoiceList] = useState([]);

  useEffect(() => {
    setInvoiceList(DATA);
  }, []);

    const statuses = ["draft", "pending", "paid"];

    // keep track of the selected/active statuses
    const [activeStatuses, setActiveStatuses] = useState([]);

    // toggle the status
    const toggleStatus = (status) => {
        if (activeStatuses.includes(status)) {
            setActiveStatuses(activeStatuses.filter((s) => s !== status));
        } else {
            setActiveStatuses([...activeStatuses, status]);
        }
    };

    // filter the invoices based on the active statuses
    const filteredInvoices = useMemo(() => {

        // if there are no active statuses, return the original list
        if (activeStatuses.length === 0) {
            return invoiceList;
        }

        // otherwise, filter the list
        return invoiceList.filter(invoice => activeStatuses.includes(invoice.status));

    },[activeStatuses, invoiceList]);
 

  return (
    <div>
      <div>
        {statuses.map((status, index) => (
          <label key={index}>
            <input
              type="checkbox"
              checked={activeStatuses.includes(status)}
              onChange={(e) => toggleStatus(status)}
            />
            <span>{status}</span>
          </label>
        ))}
      </div>

      <ul>
        {filteredInvoices.map((invoice,index) => {
          return <li key={index}>{invoice.name}</li>;
        })}
      </ul>
    </div>
  );
}

const root = ReactDOM.createRoot(
  document.getElementById("root")
).render(<App/>);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM