Я попытался свести проблему к как можно более простому примеру:
У нас есть список дочерних компонентов, каждый из которых называется NumChoice
, каждый из которых представляет число. NumChoice
завернут в React.memo
. В родительском компоненте у нас есть массив логических значений choices
, каждый из которых соответствует одному из дочерних компонентов NumChoice
. Сначала все элементы choices
равны false
. Чтобы визуализировать дочерние компоненты, мы перебираем choices
и для каждого выбора генерируем соответствующий дочерний компонент NumChoice
. Мы определяем функцию chooseDivisibles
в родительском компоненте, используя useCallback
, который вызывается из каждого дочернего компонента NumChoice
. chooseDivisibles
берет индекс NumChoice
, который его вызвал, и заменяет соответствующий элемент choices
на true
. Каждый NumChoice
имеет «красный» цвет фона, если соответствующий ему элемент в choices
равен true
, в противном случае его цвет фона - «белый».
Полный код доступен по адресу: https://codesandbox.io/s/react-rerender-l4e3c?fontsize=14&hidenavigation=1&theme=dark
Обтекание NumChoice
в React.memo
и chooseDivisibles
в useCallback
, мы ожидали перерисовать только NumChoice
компонентов, чей соответствующий элемент choices
изменяется, но React реагирует оказывает их всех. chooseDivisibles
обернуто в useCallback
, в котором нет никакой зависимости, кроме setChoices
. Кроме того, NumChoice
заключен в React.memo
, и он должен перерисовываться только в том случае, если указанные реквизиты меняются, но они этого не делают, и изменение choices
не должно иметь никакого эффекта на перерисовку NumChoice
. Если мы исключим проверку равенства chooseDivisibles
в предыдущем и следующем подпорках, это будет работать, как и ожидалось, но я утверждаю, что сравнение предыдущего и следующего chooseDivisibles
не должно влиять на повторное рендеринг NumChoice
, поскольку оно заключено в useCallback
и не зависит от choices
. Как мы можем предотвратить повторный рендеринг NumChoice
компонентов, чьи props
не изменены?