1

Helllo everyone, I have this issue where I am successfully sorting the array state of an object alphabetically using their cities but the problem is that the array that is getting visualized only updates after I search something on the UI.

I tried to look it up but still lost here is the video of what is happening https://drive.google.com/file/d/17pAwTeo8IZ6mw3dd2pxDxbfY-ToL7cjG/view?usp=sharing

here is the code

map where I visualize the list

sort function

full code here

import React, { useState, useEffect } from "react";
import "./body.css";
import Axios from "axios";
import { Button } from "@material-ui/core";

function SearchBar() {
  const [filteredData, setFilteredData] = useState([]);
  const [search, setSearch] = useState("");

  async function getUsers() {
    Axios.get("https://jsonplaceholder.typicode.com/users")
      .then((response) => {
        setFilteredData(response.data);
      })
      .catch((err) => {
        console.log(err);
      });
  }
  useEffect(() => {
    getUsers();
  }, []);

  function handleReset() {
    getUsers();

    setSearch("");
    handleClear();
  }

  const handleClear = () => {
    Array.from(document.querySelectorAll("input")).forEach(
      (input) => (input.value = "")
    );
  };

  const delItem = (id) => {
    setFilteredData(filteredData.filter((e) => e.name.localeCompare(id) !== 0));
  };

  const sort = () => {
    setFilteredData(
      filteredData.sort((a, b) => {
        return a.address.city.localeCompare(b.address.city);
      })
    );
    // console.log(sorted);
    // setFilteredData(sorted);
    console.log(filteredData);
  };

  return (
    <div>
      <form class="search-bar">
        <input
          type="input"
          name="search"
          pattern=".*\S.*"
          // requiredw
          autoComplete="off"
          placeholder="Input Text Here"
          onChange={(e) => setSearch(e.target.value)}
        ></input>
      </form>

      <Button onClick={handleReset}>Reset</Button>
      <Button onClick={sort}>Sort</Button>

      <div>
        <ul>
          {filteredData
            .filter((user) => {
              var dynamicSearch = search;

              if (
                user.name.toLowerCase().includes(dynamicSearch.toLowerCase()) ||
                user.email
                  .toLowerCase()
                  .includes(dynamicSearch.toLowerCase()) ||
                user.phone
                  .toLowerCase()
                  .includes(dynamicSearch.toLowerCase()) ||
                user.address.city
                  .toLowerCase()
                  .includes(dynamicSearch.toLowerCase())
              ) {
                return true;
              }
            })
            .map((val, index) => (
              <li className="li" key={val.id}>
                <p className="list">
                  {"Name: "}
                  {val.name} <br />
                  {"Email: "}
                  {val.email}
                  <br />
                  {"Phone: "}
                  {val.phone}
                  <br />
                  {"City: "}
                  {val.address.city}
                </p>
                <button className="delButton" onClick={() => delItem(val.name)}>
                  x
                </button>
              </li>
            ))}
        </ul>
      </div>
    </div>
  );
}

export default SearchBar;
lipo
  • 117
  • 1
  • 7
  • Add filteredData, setFilteredData to your useEffect Array [filteredData, setFilteredData] – Eddwin Paz Jul 04 '21 at 01:09
  • tried and that did not work, now after I hit sort and search something the map does not even update but I can see that the array updated correctly in my console log. Thanks though – lipo Jul 04 '21 at 01:15
  • I think you need to await getUsers() in your useEffect hook and handleReset() function. – Alex Jul 04 '21 at 01:52
  • it did not work unfortunately :( – lipo Jul 04 '21 at 02:05

1 Answers1

1

Just try with this one:

  const sort = () => {
    const sortedData = filteredData.sort((a, b) => {
    return a.address.city.localeCompare(b.address.city);
    });
    setFilteredData([...sortedData]);
  };

Problem is once you are updating the sorting data in setFilteredData function its not able to observe the changes that needs to be rendered. So always make the copy of the state variables when you are updating the values.

Divya
  • 121
  • 6