Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

162
Views
React - adding search to a table, correct way?

I added a search function for my table in React to filter out items fetched from an external webservice. Since I don't want to call the API every time you search for project I figured I'd assign the data retrieved to two different useState hooks.

One to hold the complete dataset and the other to contain the filtered items based on the search.

Could I write cleaner code without using 2 hooks? Any side effects of the way the code is handling this?

Any input is appreciated.

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Table from '@mui/material/Table';
import TableHead from '@mui/material/TableHead';
import TableBody from '@mui/material/TableBody';
import TableRow from '@mui/material/TableRow';
import TableCell from '@mui/material/TableCell';
import DeleteIcon from '@mui/icons-material/Delete';
import TextField from '@mui/material/TextField';

export default function ShowProject() {
    const [data, setData] = useState([]);
    const [filter, setFilter] = useState([])

    useEffect(() => {
        const fetchData = async () => {
            const result = await axios(
                'http://127.0.0.1:5000/pr'
            );
            setData(result.data);
            setFilter(result.data);
        }
        fetchData()
        
    }, []);

    const requestSearch = (searchedVal) => {
        const filteredRows = data.filter((row) => {
            return row.customer.toString().toLowerCase().includes(searchedVal.toString().toLowerCase());
        });
        if (searchedVal.length < 1) {
            setFilter(data)
        }
        else {
            setFilter(filteredRows)
        }
      };
    
    return (
        <div>
            <div>
                <TextField onChange={(e) => requestSearch(e.target.value)} />
                <Table>
                    <TableHead>
                        <TableRow>
                            <TableCell>Project</TableCell>
                            <TableCell>Code</TableCell>
                            <TableCell>Customer</TableCell>
                            <TableCell></TableCell>
                        </TableRow>
                    </TableHead>
                    <TableBody>
                        {filter.map(item => (
                            <TableRow key={item.db_id}>
                                <TableCell>{item.project_name}</TableCell>
                                <TableCell>{item.project_code}</TableCell>
                                <TableCell>{item.customer}</TableCell>
                                <TableCell><DeleteIcon /></TableCell>
                            </TableRow>
                        ))}
                    </TableBody>
                </Table>
            </div>
        </div>
    )
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I don't see any particular reason to use the filter state variable. You're scanning data and assigning the filtered result to filter every time your TextField changes, so why not just do the filtering directly in the JSX and instead store the query text as state? More concretely, something like the following:

  const [searchedVal, setSearchedVal] = useState("");

  return (
    <div>
      <div>
        {/* simply set the query text here instead of triggering requestSearch */}
        <TextField onChange={(e) => setSearchedVal(e.target.value)} />
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>Project</TableCell>
              <TableCell>Code</TableCell>
              <TableCell>Customer</TableCell>
              <TableCell></TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data
              .filter((row) =>
                // note that I've incorporated the searchedVal length check here
                !searchedVal.length || row.customer
                  .toString()
                  .toLowerCase()
                  .includes(searchedVal.toString().toLowerCase()) 
              )
              .map((item) => (
                <TableRow key={item.db_id}>
                  <TableCell>{item.project_name}</TableCell>
                  <TableCell>{item.project_code}</TableCell>
                  <TableCell>{item.customer}</TableCell>
                  <TableCell>
                    <DeleteIcon />
                  </TableCell>
                </TableRow>
              ))}
          </TableBody>
        </Table>
      </div>
    </div>
  );
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!