не уверен, если уместно здесь.

я есть действие и редуктор, который обновляет глобальный счетчик. Это действие запускается на быстром интервале. Редуктор возвращает новую копию состояния для каждого действия. Редуктор выглядит так:

import { handleActions } from 'redux-actions';
import { sceneTick } from './actions';

export default (state, action) => handleActions({
  [sceneTick]: (state, action) => {
    return {
      ...state,
      loop: action.payload,
    }
  },

Я используюreact-redux«sconnect метод на различных компонентах React. Не все компоненты заботятся об этом счетчике петель. Поскольку я возвращаю новое состояние в редукторе на каждом тике, все компоненты подписаныconnect получить ихmapDispatchToProps выполняется, что вызывает ненужные вызовы рендеринга React.

Один из этих компонентов выглядит так:

const mapStateToProps = (state, props) => {
  return {
    viewport: state.viewport,
    assets: state.assets,
  };
};


export default connect(mapStateToProps, {})(Component)

Хотя этот компонент не зависит отstate.loop это вызвано, чтобы повторно сделать. Это вызывает повторную визуализацию, избыточную визуализацию, многократную визуализацию, ненужную визуализацию, проблемы с производительностью и неожиданное поведение компонентов, которые не требуют повторной визуализации.

Обновить Я должен также, возможно, добавить, что яне с помощьюcombineReducers здесь и все редукторы применяются до полного состояния. Не уверен, если это уместно.

 kevzettler29 дек. 2017 г., 05:18
@Andrew Проблемы с производительностью, которые я упомянулновые рендеры неожиданное поведение происходит от компонентов с локальным состоянием, которые сбрасываются при неожиданном повторном рендеринге
 kevzettler29 дек. 2017 г., 05:30
хорошо, не проблемы производительности виртуального DOM, а повторное выполнение функций селектора, функций производных данных и распределений, вызывающих попадания GC, которые могут существовать вmapDispatchToProps функции, которые вызываются неоднократно. Да, я знаю, что их можно запомнить
 Andrew29 дек. 2017 г., 05:23
Когда я говорю новые рендеры, я имею в виду реальные изменения в компоненте. Я предполагаю, что вы знаете, что такое виртуальный / теневой DOM и как React решает, что следует перерисовать. Опять же, если я ошибаюсь, я бы очень хотел прочитать об этом, потому что это должно быть одной из самых сильных сторон React
 Andrew29 дек. 2017 г., 05:15
Проблемы с производительностью и неожиданное поведение? Можете ли вы показать мне, где вы нашли эту информацию? Потому что я не могу сказать, что согласен. Сравнения DOM очень быстрые. Это новые рендеры, которые работают медленно.
 Andrew29 дек. 2017 г., 05:42
То, что вы только что описали, не было вашим первоначальным вопросом. Redux - это самоуверенная реализация потока. Это трудно изменить. Чтобы ответить на ваш первоначальный вопрос, это невозможно, и React делает очень хорошую работу, когда дело доходит до производительности. Опять же, если я ошибаюсь, я был бы очень заинтересован в ресурсах, с которых вы обнаружили эту информацию.

Ответы на вопрос(3)

Решение Вопроса

Reduxconnect принимаетareStatesEqual Опция функции, которая может использоваться, чтобы сузить проверки на равенство для определенных ветвей состояния.

export default connect(
  {},
  {},
  null,
  {
    areStatesEqual: (next, prev) => {
      return (
        prev.branch === next.branch
      );
    }
  }
)(Component);

используйте ответshouldComponentUpdate метод.

https://reactjs.org/docs/react-component.html#shouldcomponentupdate

Обновление: CombineReducers будет иметь значение. Попробуйте изменить

return {
   ...state,
   loop: action.payload,
}

в

state.loop = ...action.payload;
return state;

Если вы не хотите изменять состояние, вы должны использовать combReducer с циклом в качестве собственного редуктора. Так как вы не использовали зернокомбайн, я превратил состояние в rootReducer. Это похоже на то, что автор редукса делает с CombineReducers (видео) за исключением того, что nextState был создан в combReducer.

 Andrew29 дек. 2017 г., 05:29
Вы не можете остановить повторное использованиеshouldComponentUpdate, Это просто событие жизненного цикла.
 SILENT29 дек. 2017 г., 05:33
@Andrew ShouldComponentUpdate не останавливает повторное рендеринг, но может уменьшить их, если это происходит из-за входящих изменений в подпорках, таких как изменения состояния редукции.
 SILENT29 дек. 2017 г., 05:32
Подключиться очень эффективно. Он не будет отображаться в файле state.loop, если он не используется в компоненте. Скорее всего, другой Редуктор обновляется неожиданно. Инструменты Redux Dev полезны в этой ситуации.
 kevzettler29 дек. 2017 г., 05:23
Этот метод требуетshouldComponentUpdate инструментарий в каждом компоненте, который не связан с обновляемой ветвью состояния, что требует больших усилий.
 kevzettler29 дек. 2017 г., 05:38
@SILENT Я добавил обновление в ОП оcombineReducers не уверен, если уместно здесь.

connect является чистым и, следовательно, делает поверхностное сравнение реквизитов, которые он должен предоставить компоненту, т.е. он реализуетshouldComponentUpdate метод в его реализации и не вызывает повторного рендеринга для подключенного компонента, если данные возвращаются изmapStateToProps не меняется

Для Redux важно отслеживать изменение состояния для каждого изменения, потому что только тогда он может принять решение, обновлять его или нет.

Так как компонент Pure выполняет поверхностное сравнение состояний и реквизитов, вы должны убедиться, что ваши состояния не сильно вложены

 Shubham Khatri10 апр. 2018 г., 07:54
Это может быть проблема с вашим селектором, который каждый раз возвращает новый объект, и это нарушит поверхностное сравнение
 vsync20 июл. 2018 г., 11:52
@ ШубхамКхатри - уточни пожалуйста. какой «селектор» и какой «новый объект» каждое отправленное действие возвращает новыйгосударство Объект ..
 kevzettler10 апр. 2018 г., 07:52
Я не смог воспроизвести это поведение. Разве я не должен возвращать новый объект формы mapStateToProps? разве это не сделает недействительным мелкое сравнение?

Ваш ответ на вопрос