How to fetch data with useEffect and then render based on selected filter option in React Js

Viewed 40

I am fetching the data using useEffect then want to later change or update table based on filter selection but the problem is it's exactly rendering what I am selecting from filter instead it's rendering previous selected option data. for example if I select pending from filter first then resolved it will render pending on selection on resolved.

I don't know where I am making mistakes.

QueryView.js

import { useEffect, useState } from 'react';

const QueriesView = () => {
    const [queryData, setqueryData] = useState([])
    const [status, setStatus] = useState("Pending")
    const [data,setdata] = useState([])

    const getStatus = (e) => {
        setStatus(e.target.value)

        setdata( queryData.filter(ele=> ele.querystatus === status))
    }

    useEffect(() => {
        let url = "https://script.google.com/macros/s/AKfycbykZx2qtz39U5j8TwDRVuziKfoLzF6YkYvDL6Ejoj822Vg9MPe1pDS9PX86IeP1Kzw82Q/exec?request=getQueriesData";
        const fetchData = async () => {
            try {
                const response = await fetch(url);
                const json = await response.json();
                setqueryData(json)
            }
            catch (err) {
                console.log("catching error")
            }
        }
        fetchData();
    }, [])


    return (
        <>       
            <div className='container mt-2'>
            <div className='row'>
                <select className="form-select form-select-sm" aria-label=".form-select-sm example"
                name='status'
                onChange={getStatus}
                value={status.value}
                >
                    <option value="Pending">Pending</option>
                    <option value="Resolved">Resolved</option>
                    <option value="Rejected">Rejected</option>
                </select>
                </div>
                <table class="table table-hover table-sm">
                    <thead class="thead-dark">
                        <tr>
                            <th scope="col">Date</th>
                            <th scope="col">Query Number</th>
                            <th scope="col">Email</th>
                            <th scope="col">Full Name</th>
                            <th scope="col">Phone No.</th>
                            <th scope="col">Status</th>
                            <th scope="col">Details</th>
                        </tr>
                    </thead>
                    <tbody>
                        {data.map(ele => (
                            <tr>
                                <th scope="row">{ele.querydate}</th>
                                <td>{ele.querynumber}</td>
                                <td>{ele.email}</td>
                                <td>{ele.firstname} {ele.lastname}</td>
                                <td>{ele.contact}</td>
                                <td>{ele.querystatus}</td>
                                <td><button type='button'>Details</button></td>
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        </>
    )
}

export default QueriesView;
1 Answers

UPDATE: When the data is fetched in the useEffect, it must be filtered again according to the currently selected status:


  useEffect(() => {
    let url =
      "https://script.google.com/macros/s/AKfycbykZx2qtz39U5j8TwDRVuziKfoLzF6YkYvDL6Ejoj822Vg9MPe1pDS9PX86IeP1Kzw82Q/exec?request=getQueriesData";
    const fetchData = async () => {
      try {
        const response = await fetch(url);
        const json = await response.json();
        setqueryData(json);
        // set filtered again
        setdata(json.filter((ele) => ele.querystatus === status));
      } catch (err) {
        console.log("catching error");
      }
    };
    fetchData();
  }, []);

Here is a working example: https://codesandbox.io/s/exciting-stitch-k11sdd?file=/src/QueriesView.js


When using .map() to render a list of items, you always must provide a key so React can identify the corresponding entries: https://reactjs.org/docs/lists-and-keys.html#keys

For example using the array index (another field than index would better):

{data.map((ele, index) => (
    <tr key={index}>
            <th scope="row">{ele.querydate}</th>
            <td>{ele.querynumber}</td>
            <td>{ele.email}</td>
            <td>{ele.firstname} {ele.lastname}</td>
            <td>{ele.contact}</td>
            <td>{ele.querystatus}</td>
            <td><button type='button'>Details</button></td>
    </tr>
))}
Related