Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

199
Vistas
Filtering data and returning it next to the "permanent" data - react

I added a TextField from the MUI library, and used a useRef hook to capture the value "live" as the user types something. The intention is to filter only the rates which include the characters he types. As of right now:

Object.keys(rates["rates"]) // ["EUR", "RON", "CZK", ...]

I added a form, and I want it to stay persistent, but the buttons should change dynamically. If the user has not typed anything I want to return everything (like nothing is filtered)

My try:

import React, {useEffect, useRef, useState} from 'react'
import Button from '@mui/material/Button';
import CircularProgress from '@mui/material/CircularProgress';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';

const RatesButton = () => {
    const rateRef = useRef('')
    const [rates, setRates] = useState([]);
    useEffect(
        () => {
            fetch("https://api.vatcomply.com/rates")
                .then(ratesResponse => ratesResponse.json())
                .then(rates => setRates(rates));
        }
        , [])


    if (rates.length === 0) {
        return (
            <Box sx={{display: 'flex', justifyContent: 'center'}}>
                <CircularProgress/>
            </Box>
        )
    }

    const rateSearch = () => {
        Object.keys(rates["rates"]).filter(
            rate => rate.includes(rateRef.current.value)
        ).map(rate => {

                return (
                    <Button>
                        {rate}
                    </Button>
                )
            }
        )

    }

    return (
        <>
            <br/>
            <TextField id="rate-search" onChange={rateSearch} inputRef={rateRef} label="Rate" variant="outlined"/>
        </>
    )
}


export default RatesButton

It works nicely I think, I can access the reference of the input of the user, filter all the rates that contain the letters, and map each one to a MUI Button. The problem is that they don't show somehow, and I am pretty lost, it is pretty confusing how I can return from two different functions at the same time, while keeping one persistent (the input field)

Picture of the input

The buttons do not show unfortunately...

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You should use controlled mode and store your TextField's value in a state using useState instead of useRef because changing the ref value doesn't trigger a re-render so the UI doesn't get updated. There are a lot of other wrong things in your code, I've fixed it all, feel free to ask me if you don't understand anything:

const RatesButton = () => {
  const [value, setValue] = useState("");
  const [rates, setRates] = useState({});

  useEffect(() => {
    fetch("https://api.vatcomply.com/rates")
      .then((ratesResponse) => ratesResponse.json())
      .then((rates) => setRates(rates.rates ?? {}));
  }, []);

  return (
    <>
      {Object.keys(rates).length === 0 && (
        <Box sx={{ display: "flex", justifyContent: "center" }}>
          <CircularProgress />
        </Box>
      )}
      {Object.keys(rates)
        .filter((rate) => rate.toLowerCase().includes(value.toLowerCase()))
        .map((rate) => {
          return <Button>{rate}</Button>;
        })}
      <br />
      <TextField
        id="rate-search"
        onChange={(e) => setValue(e.target.value)}
        // inputRef={value}
        label="Rate"
        variant="outlined"
      />
    </>
  );
};

Live Demo

Codesandbox Demo

about 4 years ago · Juan Pablo Isaza Denunciar

0

    import React, {useState} from 'react';
    import { throttle } from 'lodash';

    const RatesButton = () => {
      const [value, setValue] = useState("");
      const [rates, setRates] = useState({});

      useEffect(() => {
        fetch("https://api.vatcomply.com/rates")
          .then((ratesResponse) => ratesResponse.json())
          .then((rates) => setRates(rates.rates ?? {}));
      }, []);
      
      const handleChange = (e) => setValue(e.target.value);
      
      // it will prevent multiple render during fast typing
      const throttledChange = throttle(handleChange, 400);

      return (
        <>
          {Object.keys(rates).length === 0 && (
            <Box sx={{ display: "flex", justifyContent: "center" }}>
              <CircularProgress />
            </Box>
          )}
          {Object.keys(rates)
            .filter((rate) => rate.toLowerCase().includes(value.toLowerCase()))
            .map((rate) => {
              return <Button>{rate}</Button>;
            })}
          <br />
          <TextField
            id="rate-search"
            onChange={throttledChange} // don't use arrow function
            label="Rate"
            variant="outlined"
          />
        </>
      );
    };
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda