Table filter by name in React

Asked

Viewed 2,216 times

0

I’m developing an application in React where it shows a table with data from an Array that comes from an API, put a filter to search by name and the table changes according to the user’s input. The filter up to the part that searches the Array and shows on screen this all OK, my problem arises when the user deletes the field the Array does not return to the original format, what causes this is that the function to filter the data change my state where are the original data and consequently change the component that contains the map() rendering my filter like this, but it does not return to the original by deleting the filter

Main component:

import React, {useState, useEffect} from 'react';
import './App.css';
import axios from 'axios'
import global from './Global.json'
import Table from './Table'

function Initial() {

    const [data, setData] = useState([])   
    const [dataKeys, setDataKeys] = useState([])

    useEffect( (data) => {
        const fetchData = async (data) => {
          try{
            const requestData = await axios.get(`${global.URL}:3336/list-items/`)
            setData(requestData.data)
            setDataKeys(Object.keys(requestData.data[0]))
          }catch(err){}

        }
        fetchData(data)
      }, []);

    function handleInput(e){
        var input = document.getElementById('input-table').value
        setData(searchTable(input, data))
      }

    function searchTable(value, data){
        var filteredData = []
        for(var i = 0; i < data.length; i++){
           value = value.toLowerCase()
           var user = data[i].usuario.toLowerCase() 
           if(user.includes(value)){
             filteredData.push(data[i])
            }
        }
        return filteredData
    }


    return(
        <>
        <br />
        <br />
            <input 
            className="form-input" 
            onKeyUp={() => {
                    handleInput()
                }} 
                id="input-table" 
                placeholder="Ache um Usuario" />
            <br />
            <br />
            <Table dataKeys={dataKeys} data={data} />
        </>
    )
}

export default Initial

Table component:

import React from 'react';
import './App.css';



const Table = ({dataKeys, data}) => (
    <table className="table">
    <thead className="thead-dark">
      <tr>
        {
          dataKeys.map(keys => {
            return(
              <th scope="col" key={keys}>{keys}</th>
            )
          })
        }

      </tr>
    </thead>
    <tbody>
      {
        data.map(data => {
          return(
            <tr data={data.id}>

              <th scope="row" >{data.id}</th>
              <th scope="row">{data.usuario}</th>
              <th scope="row">{data.telefone}</th>
              <th scope="row">{data.loja}</th>
              <th scope="row">{data.departamento}</th>
              <th scope="row">{data.cargo}</th>
            </tr>
          )
        })
      }


    </tbody>
  </table>
)

export default Table

One of my solutions was to move to the useEffect for it to execute when a state timer is changed and in function hadleClick I alter it after a setTimeout() 6 seconds. However, it is not an elegant solution.

I’m days away from a solution to that.

  • Voce meant that when the user deletes everything he had written in the filter field, the table should re-display all items again?

  • yes exactly that but I could not get a logic q React accepted, doing this with jquery and or javascript works because I have to control when rendering parameter

1 answer

2


Well, doing some tests here, I think I figured out your mistake.

First, let’s redo this input as follows:

<input
  className="form-input"
  onChange={handleInput} // nao precisa colocar {() => handleinput()}.
                         // e mude de `onKeyPress` para `onChange`.
  id="input-table"
  placeholder="Ache um Usuario"
/>

In his job handleInput let’s rewrite it this way:

function handleInput(e) {
 const inputValue = e.target.value; // e.target corresponde ao elemento input.
 setData(searchTable(inputValue));  // assumindo `data` como propriedade global do 
                                    // estado Nao precisa passar como parametro.
}

Create a state to save your API’s original data:

const [originalData, setOriginalData] = useState();

In his useEffect(), save the original data on originalData:

setOriginalData(requestData.data);

Now comes the important thing. In your role searchTable, let’s just pass value as parameter and we will write a if where if the length of value for 0, means the user has deleted everything from the input, so we want the initial state of the data be restored:

function searchTable(value) {
 const filteredData = [];

 if (value.length === 0) {
   return originalData; // ESTE RETORNO IRA RESTAURAR OS DADOS ORIGINAIS DO 
                       // DATA
 }

 for (let i = 0; i < data.length; ++i) {
  const newValue = value.toLowerCase(); // nao redeclare o value.

  const user = data[i].usuario.toLowerCase();

  if (user.includes(newValue)) {
    filteredData.push(data[i]);
  }
 }
 return filteredData;
}

I think that might be the solution. Test and give me the feedback.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.