TransWikia.com

Problemas ao renderizar componente react após array filter

Stack Overflow em Português Asked by Aniello Sansone Filho on December 4, 2021

Boa noite,
Tenho um método que filtra um array e seta a variável de estado "transactions" com o resultado deste filter = newArrayTransactions, conforme podem abaixo.

O componente filho que passa o valor para o filter é um input do tipo text que estou usando o método onChange nele.
A ideia é renderizar dinamicamente outro componente que mostra todas as transactions na tela, com base nesse filtro que é digitado.
Funciona bem quando digito, mas quando deleto alguma letra "parece" que o filter não é executado.

const handleChangeInput = (value) =>{
const newArrayTransactions = transactions.filter(transaction =>{
  return transaction.description.toLowerCase().indexOf(value.toLowerCase())!== -1
})
setTransactions(newArrayTransactions)

Aqui esta a chamado ao componente filho passando a função acima

<CreateAndSearch onHandleInput={handleChangeInput}/>

Aqui esta o componente filho chamado acima

export default function CreateAndSearch({onHandleInput}) {

const handleInput = (e) =>{
    onHandleInput(e.target.value)
}

return (
    <div className='main-createAndSearch'>
        <button className='waves-effect waves-light btn'>
            <i className="material-icons left">add</i>
            NOVO LANÇAMENTO
        </button>
        <div className="input-field">
            <input id="filtro" type="text" onChange={handleInput}/>
            <label hmtlfor="filtro">Filtro</label>
        </div>
    </div>
)

}

One Answer

O método filter irá sempre filtrar o array cujo método é aplicado. Isso jamais aumenta seu tamanho pro valor original, filter na melhor das hipóteses irá retornar uma cópia do transactions anterior. Ou seja, você precisa manter uma referência ao array original com todas as opções. A seguir, um exemplo funcional de filtragem. Usei o items como constante, mas nada te impede de passá-lo como props.

import React, { useState } from "react";
import faker from "faker";
import "./styles.css";

const items = Array.from(Array(100).keys()).map(() => ({
  description: faker.commerce.productName(),
  id: faker.random.uuid()
}));

const filterFunction = value => transaction =>
  transaction.description.toLowerCase().indexOf(value.toLowerCase()) !== -1;

function CreateAndSearch({ onHandleInput }) {
  const handleInput = e => {
    onHandleInput(e.target.value);
  };

  return (
    <div className="main-createAndSearch">
      <button className="waves-effect waves-light btn">
        <i className="material-icons left">add</i>
        NOVO LANÇAMENTO
      </button>
      <div className="input-field">
        <input id="filtro" type="text" onChange={handleInput} />
        <label hmtlfor="filtro">Filtro</label>
      </div>
    </div>
  );
}

export default function App() {
  const [transactions, setTransactions] = useState(items);

  const handleChangeInput = value => {
    setTransactions(items.filter(filterFunction(value)));
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>

      <CreateAndSearch onHandleInput={handleChangeInput} />

      <ul>
        {transactions.map(item => (
          <li key={item.id}>{item.description}</li>
        ))}
      </ul>
    </div>
  );
}

Answered by Rodrigo Amaral on December 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP