@lexstile

Как оптимизировать перерисовку в цикле?

Чтобы все работало, мне приходится передавать внутрь < Position /> мемоизированные коллбэки onAddPosition и onRemovePosition.
Если я буду делать что-то типа:
() => cart.add(dish);

// внутри <Position /> происходит что-то типа
onClick={onAddPosition(position)}

Но тогда будет каждый раз новая ссылка на коллбэки.
Дополнительно обернуть в useCallback не получится, потому что нужно передавать аргумент.
Можно ли как-то иначе решить проблему? (очень не хочется передавать props position)
export const Category = memo(({ category, onChangeInView }) => {
  const positions = useSelector((state) => get(state, 'cart.positions'));
  const cart = useCart();

  return (
    <InView key={category.id} threshold="0" rootMargin="-50% 0% -50% 0%" onChange={onChangeInView(category.id)}>
      <Group getRootRef={category.ref} header={<Header mode="secondary">{category.name}</Header>}>
        <Div>
          <Grid.Row>
            {category.dishes.map((dish) => (
              <Grid.Col key={dish.id} xs={6}>
                <Position
                  position={dish}
                  quantity={get(positions, `${dish.id}.quantity`, 0)}
                  onAddPosition={cart.add}
                  onRemovePosition={cart.remove}
                />
              </Grid.Col>
            ))}
          </Grid.Row>
        </Div>
      </Group>
    </InView>
  );
});

export const useCart = () => {
  const dispatch = useDispatch();

  const add = useCallback((position) => () => dispatch(cartSlice.actions.addPosition(position)), [dispatch]);
  const remove = useCallback((position) => () => dispatch(cartSlice.actions.removePosition(position)), [dispatch]);

  return {
    add,
    remove,
  };
};

Этот материал читал.
  • Вопрос задан
  • 56 просмотров
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
Этот материал читал.

вроде должно подойти (см. там вариант с useMemo)

только у тебя параметр для мемоизации - не примитивное значение, а объект (position, он же dish). Потому укажи кастомный serializer, который просто возвращает position.id.

в целом способ прикольный, но надо помнить, что в отрендеренном родительском компоненте (в твоем примере - Category) мемоизация будет жить постоянно до размонтирования. И если будут часто меняться ключи, а компонент будет жить очень долго, то в кэше накопится много элементов. На этот случай в опциях fast-memoize можно задать свой кастомный кэш с ограничением на размер и удалением старых элементов. Впрочем, полагаю, в твоем случае до такого не дойдет.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы