Скажите React / Redux, чтобы он игнорировал ссылки на объекты и просто делал глубокую проверку на равенство - PullRequest
2 голосов
/ 27 февраля 2020

Проблема - мой компонент обновляется, даже если входные данные не изменились, и я подозреваю, что это из-за изменения ссылки на объект при глубоком сравнении.

У меня есть редуктор, например, так:

const getDefaultState = () => ({
  mainNotifMessage: '(unknown message)',
  notifDetails: '(unknown notification details)',
  snackBarOpen: true
});

export type CPAction = {type: string, val: object}

export const notifsReducer = (state = getDefaultState(), action: CPAction) => {

  switch (action.type) {
    case c.NOTIFY_ERROR:

      return {
        ...state,
        ...action.val
      };

    default:
      return {
        ...state
      };
  }
};

, а затем в компоненте, который у меня есть:

function mapStateToProps(state: RootState) {
  return {
    notifs: state.notifs
  };
}

Я думаю, что происходит, что state.notif всегда получает новую ссылку на объект, поэтому React / Redux всегда обновляет мой компонент, даже если нет изменений. Но если я изменю это на:

function mapStateToProps(state: RootState) {
  return {
    mainNotifMessage: state.notifs.mainNotifMessage,
    snackBarOpen: state.notifs.snackBarOpen,
    severity: state.notifs.severity,
    notifDetails: state.notifs.notifDetails
  };
}

, тогда он не обновит компоненты. Есть ли способ заставить Redux / React всегда выполнять глубокое сравнение и не возвращать рано при разнице ссылок на объекты?

1 Ответ

1 голос
/ 27 февраля 2020

Я думаю, что происходит то, что state.notif всегда получает новую ссылку на объект, поэтому React / Redux всегда обновляет мой компонент, даже если нет изменений.

По умолчанию React-Redux решает, отличается ли содержимое объекта, возвращаемого из mapStateToProps, с помощью сравнения === (проверка "неглубокого равенства") для каждого поля возвращаемого объекта.

 default:
  return {
    ...state
  };

Вы возвращаете новый ссылка каждый раз в вашем состоянии по умолчанию. Поэтому, когда вы читаете значения с использованием точечной нотации, вы получаете те же значения.

Но для Javascript это новая ссылка на объект, поэтому React-Redux будет пытаться повторно визуализировать компонент.

Вы можете просто сделать return state вместо того, чтобы распространять его и создавать новую ссылку на объект в случае default вашего редуктора.

Ссылка: https://react-redux.js.org/using-react-redux/connect-mapstate#return -values-define-if -Ваш-компонентные повторно делает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...