Home > Net >  How to handle data display with multiple checkboxes in React Js
How to handle data display with multiple checkboxes in React Js

Time:09-24

I'm working on a app where on component load after fetch GET API, list of cars are displayed to user. There're also multiple checkboxes which allow user to filter displayed data. I'm filtering the results depending on selected checkbox value, but the problem is that I don't know how to display first whole list of cars, and only then filtered results ( if user selects any checkbox). My code is:

import React, { useState, useEffect } from "react";

export default function CarsMain() {
  const [filterList] = useState([
    {
      value: "BMW"
    },
    {
      value: "Hyundai"
    },
    {
      value: "Mercedes"
    }
  ]);
  const [data, setData] = useState([]);
  const [filteredData, setFilteredData] = useState([]);

  useEffect(() => {
   
      fetch(url)
        .then(function (response) {
          return response.json();
        })
        .then(function (res) {
          setData(res);
        })
        .catch(function (e) {
          console.log(e);
        })
    );
  }, []);


  function handleCheckbox(value, e) {
    if (e.target.checked) {
      let selectedData = data.filter((d) => d.model === value);

      setFilteredData([...filteredData, ...selectedData]);
    } else {
      let unselected = filteredData.filter((d) => {
        return d.model !== value;
      });
      setFilteredData(uncheckedData);
    }
  }

  return (
  
          <div >
            {filterList?.map((v) => {
              return (
                <div key={v.model}>
                  <input
                    type="checkbox"
                    onChange={(e) => handleCheckbox(v.model, e)}
                  />
                </div>
              );
            })}
          </div>
           {filteredData.map((d) => {d.model})

        </div>
      </div>
    </div>
  );
}

checkbox select works fine, when BMV is selected, only cars with model === "BMV" are displayed, the issue is that when page loads there is no data displayed, only after I select one of the checkboxes, the list of cars would be displayed. I can't seem to figure out how to display the whole list at page load an then filteredData ( when/if user selects checkbox). I'm mapping over filteredData because if I map over data(stored from API), checkbox selection doesn't work. How can I display data received from API on page load and when no checkbox is selected, and only selected car models after user clicks checkbox. Any help and advise are greatly appreciated.

CodePudding user response:

try add data to useEffect dependencies array

  useEffect(() => {
  ...
  }, [data]);

CodePudding user response:

Initially, when there are no checkboxes selected, you want to display the whole list, you can update the useEffect to store all the res data in the filteredData state array. That way, initially, when no checkbox is selected, all the data will be rendered on the screen in the map function.

  useEffect(() => {
      fetch(url)
        .then(function (response) {
          return response.json();
        })
        .then(function (res) {
          setData(res);
          setFilteredData(res)
        })
        .catch(function (e) {
          console.log(e);
        })
    );
  }, []);

You also need to update handleCheckbox function, in case when the user selects any checkbox first time, we don't need to destructure the filteredData array, otherwise there will be duplicates. We can check for the first time checkbox selection by comparing the length of the filteredData and the data.

function handleCheckbox(value, e) {
    if (e.target.checked) {
      let selectedData = data.filter((d) => d.model === value);
      setFilteredData(filteredData.length && filteredData.length === data.length ? [...selectedData] : [...filteredData, ...selectedData]);
    } else {
      let unselected = filteredData.filter((d) => {
        return d.model !== value;
      });
      setFilteredData(uncheckedData);
    }
  }

  • Related