0

I'm trying to filter some companies array -that is being shown in a table- using multiple checkboxes. These checkboxes returns an array of strings with some status. For example: ['accepted', 'pending', 'declined'];. The problem is that while the checkboxes returns the status OK, I cannot manage to filter the companies array with the checkboxes data.

Here is my main code:

function App() {

  const [filters, setFilters] = useState([]);
  const [companies, setCompanies] = useState([
    { id: 1, status: "accepted", name: "001", date: "01/01/2022" },
    { id: 2, status: "accepted", name: "001", date: "01/01/2022" },
    { id: 8, status: "accepted", name: "001", date: "10/04/2022" },
  ]);

  //HERE I TRY TO FILTER MY COMPANIES ARRAY WITH THE SELECTED CHECKBOXES
  const showFilteredCompanies = (filters) => {
    return [...companies].filter((company) => {
      return filters.includes(company.status);
    });
  }


  //Inside data I have my array of selected status like this: ['accepted', 'pending', 'declined']

  const handleFilters = (data) => {
    
    let newFilters = {...filters};
    newFilters = data;
    setFilters(newFilters);

    // THIS CONSOLE.LOG SHOWS THE FILTERED ARRAY OF COMPANIES JUST FINE
    console.log(showFilteredCompanies(newFilters));

    const filtered = showFilteredCompanies(newFilters);

    //BUT WHEN I TRY TO SAVE MY COMPANIES FILTERED ARRAY IN MY STATE THE FILTERING DOESN'T WORK AS IT SHOULD
    console.log(filtered);
    setCompanies(filtered);
  }

  return (
    <div className="App">

      <Checkbox 
        handleFilters={data => handleFilters(data)}
      />

      {/* companies list */}
      <div>
        {companies.length ? 
          (
            <table>
              <thead>
                <tr>
                  <th>ID</th>
                  <th>Estado</th>
                  <th>nombre</th>
                  <th>Fecha</th>
                </tr>
              </thead>
              <tbody>
                {companies.map((company, i) => (
                    <tr key={i}>
                      <td>{company.id}</td>
                      <td>{company.status}</td>
                      <td>{company.name}</td>
                      <td>{company.date}</td>
                    </tr>
                  )
                )}
              </tbody>
            </table>   
          ) : (
            <h2>No hay compañías para mostrar</h2>
          )
        }
      </div>

      {/* list length */}
      <div>
          <h3>Cantidad de compañías: {companies.length}</h3>
      </div>
    </div>
  );
}

export default App;

I was expecting to filter my companies array with all the strings of my checkboxes data array to show only the companies.status that matches the selected status of the checkboxes

1
  • You should not be setting filtered companies as state. The checkboxes are state because they are influenced by user actions. The filtered companies are a derived product of this state. Just filter on the fly. Commented Dec 16, 2022 at 3:20

1 Answer 1

1

It seems that the filtering of companies might not need to be another state, and could possibly be chained with map() in the output for simplicity.

Not sure if it would work without testing in the use case, but assuming that filters are updated just fine as posted, perhaps try omit showFilteredCompanies and setCompanies in handleFilters, and add in the output:

{ /* companies list with filter before map */ }
<div>
  {companies.length ? (
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Estado</th>
          <th>nombre</th>
          <th>Fecha</th>
        </tr>
      </thead>
      <tbody>
        {companies
          .filter((company) =>
            filters.length > 0 ? filters.includes(company.status) : true
          )
          .map((company, i) => (
            <tr key={i}>
              <td>{company.id}</td>
              <td>{company.status}</td>
              <td>{company.name}</td>
              <td>{company.date}</td>
            </tr>
          ))}
      </tbody>
    </table>
  ) : (
    <h2>No hay compañías para mostrar</h2>
  )}
</div>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.