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

110
Vistas
Optimizing performance for arbitrarily large number of inputs in react

Specifically with Material UI, I'm trying to render a large number of inputs (> 100) and manage a global state effectively. I run into serious performance issues like input lag at around 50 inputs but the lag is still noticeable at around 10 inputs. I've narrowed it down to the Material UI <TextField /> component because if I change that to regular input element, there is virtually no lag which is to be expected since there's a lot more happening in a MUI component.

What I don't know however, is if changing how I manage state might help performance. I've tried 2 state management approaches: traditional react with useState hook and Recoil.

In addition to the 2 approaches above, I also tried a combination of recoil and traditional react by using useState and useSetRecoilState in filter components so that all filters wouldn't re-render on change to recoil state since they are only writing not reading but still no luck.

EDIT
Turns out I forgot to test putting values in more than 1 input... When you enter a value in another input, the previously entered input will get wiped. I'm thinking it's because in my handleChange function, I replace an item in filterList but filterList is now an old outdated reference so it does not have the previously set value. Back at square one now, because if I read state in the filter component, then the component will re-render which eliminates the memo performance boost.

EDIT 2
Posted solution below

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

0

Looks like I was trying to use recoil when I really didn't need to. Using React.memo along with React.useState and moving the global state edit up to the parent ended up being all I needed.

Filters.js

const filterMaker = (length) => {
  let filters = [];
  for (let i = 0; i < length; i++) {
    if (i % 2 === 0) {
      filters.push({ name: `filter-${i}`, type: 'a', active: { value1: '' } });
    } else {
      filters.push({
        name: `filter-${i}`,
        type: 'b',
        active: { value1: '', value2: '' },
      });
    }
  }
  return filters;
};

function replaceItemAtIndex(arr, index, newValue) {
  return [...arr.slice(0, index), newValue, ...arr.slice(index + 1)];
}

export default function Filters() {
  const [filterList, setFilterList] = useRecoilState(filterListState);

  useEffect(() => {
    setFilterList(filterMaker(200));
  }, []);

  const handleChange = (filter, name, value, index) => {
    setFilterList((prevState) => {
      return replaceItemAtIndex(prevState, index, {
        ...filter,
        active: {
          ...filter.active,
          [name]: value,
        },
      });
    });
  };

  return (
    <div>
      {filterList.map((filter) =>
        filter.type === 'a' ? (
          <FilterA
            key={filter.name}
            filter={filter}
            filterList={filterList}
            handleChange={handleChange}
          />
        ) : (
          <FilterB
            key={filter.name}
            filter={filter}
            filterList={filterList}
            handleChange={handleChange}
          />
        )
      )}
    </div>
  );
}

FilterA.js

export const FilterA = memo(
  ({ filter, filterList, handleChange }) => {
    const [values, setValues] = useState(filter.active || {});
    const index = filterList.findIndex((item) => item.name === filter.name);

    const handleLocalChange = ({ target: { name, value } }) => {
      setValues((prevState) => {
        return { ...prevState, [name]: value };
      });
      handleChange(filter, name, value, index);
    };

    return (
      <Box mb={1}>
        <Typography>{filter.name}</Typography>
        <TextField
          variant="standard"
          name="value1"
          label="value1"
          value={values.value1 || ''}
          onChange={handleLocalChange}
        />
      </Box>
    );
  },
  (prevProps, nextProps) => {
    if (prevProps.filter.active.value1 === nextProps.filter.active.value1) {
      return true;
    }
    return false;
  }
);
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