Conrad
Conrad

Reputation: 51

why SearchBar not retaining entered text in results - in React.js

I have some issues with my searchBar.jsx

Upon typing a word into the SearchBar, the expected search results are displayed correctly. However, when I proceed to delete the entered text, the displayed results revert to their original state. Ideally, I want the SearchBar to retain and display the previously fetched results even after the text has been cleared.

I tried many things that i can't post here as it is too long but my fanal test is as followed :

import { useEffect, useState } from "react";
import axios from "axios";
import SecurityViolation from "./../Components/SecurityViolation";
import "./../Style/SecurityViolation.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";

function Violation() {
    const [data, setData] = useState([]);
    const [searchTerm, setSearchTerm] = useState("");
    const [filteredData, setFilteredData] = useState([]);
    const [previousResults, setPreviousResults] = useState([]);

    useEffect(() => {
        axios
            .get(`http://localhost:5005/securityViolations`)
            .then((response) => {
                console.log(response.data);
                setData(response.data);
                setFilteredData(response.data);
                setPreviousResults(response.data);
            })
            .catch((error) => {
                console.log("Error fetching Data: ", error);
            });
    }, []);

    // search bar
    useEffect(() => {
        const filterData = () => {
            if (searchTerm.trim() === "") {
                setFilteredData(data);
            } else {
                setFilteredData(
                    data.filter(
                        (item) =>
                            item.user.familyName.toLowerCase().includes(searchTerm.toLowerCase()) ||
                            item.team.toLowerCase().includes(searchTerm.toLowerCase())
                    )
                );
            }
        };

        filterData();
    }, [searchTerm, data]);
    // --------

and about my div with the searchbar


 <div className="searchBar_block">
                <FontAwesomeIcon icon={faMagnifyingGlass} />

                <input
                    type="text"
                    placeholder="Search all violation ..."
                    className="search"
                    value={searchTerm}
                    onChange={(e) => setSearchTerm(e.target.value)}
                />
            </div>

            {filteredData.length === 0 ? (
                <p>Unfortunately, no data found</p>
            ) : (
                <table>

Thank you for your time

Upvotes: 0

Views: 44

Answers (1)

possum
possum

Reputation: 2927

There's a number of variations on the logic you can use, but in general if you want to only update the filtered results when you are adding text but not deleting it in the search term, you can implement some additional state to check how the search term has changed.

const [previousSearchTerm, setPreviousSearchTerm] = useState(searchTerm);

The onChange function then can update these accordingly replacing (e) => setSearchTerm(e.target.value) with something like

(e) => {
    setPreviousSearchTerm(searchTerm)
    setSearchTerm(e.target.value)
}

and then conditionally updating the filtered data based on the differences

if (searchTerm.trim() === "") {
    setFilteredData(data);
} else {
    if (searchTerm.len() > previousSearchTerm.len()) {
        setFilteredData(
            data.filter(
                (item) =>
                    item.user.familyName.toLowerCase().includes(searchTerm.toLowerCase()) ||
                    item.team.toLowerCase().includes(searchTerm.toLowerCase())
            )
        );
    }
}

Upvotes: 0

Related Questions