Это сложный вопрос о React / Redux.
Кажется, я могу сделать каждый компонент моего приложения основанным на одном контексте (в качестве потребителей контекста) и использовать этот контекст в качестве единственного хранилища данных , Но затем, когда меняется контекст, каждый отдельный компонент моего приложения будет перерисован - и это нежелательно.
1) Когда я использую React и Redux вместо этого, чтобы каждый компонент перерисовывается как можно меньше, используя connect()
и получая данные хранилища Redux как props
, в React Developer Tool также есть Context.Provider
, но я не вижу Context.Consumer
- почему нет Context.Consumer
- как компоненты могут получать данные, если нет потребителя контекста?
2) Redux каким-то образом просто добавляет так называемый «Connect» HO C (более высокий порядок) компонент), и добавьте props
к нашим компонентам, чтобы наши компоненты повторно отображались при смене реквизита? Но я думал, что наши компоненты тоже находятся в этом «глобальном контексте Redux», поэтому, когда глобальный контекст Redux меняется, почему он не вызывает повторную визуализацию нашего компонента? Делается ли Connect
потребителем контекста, а нашим компонентом - не потребителем контекста, а просто получает "реквизит"?
3) Я думал, что есть правило: когда state
или props
изменить, компонент и все поддерево будет повторно визуализировать. А как насчет контекста? Это немного отличается? То есть, когда контекст изменяется, то только компоненты, являющиеся потребителями контекста, будут перерисованы повторно, но если в этом поддереве есть потомки, которые не являются потребителями контекста, будет ли не перерисовываться? Иначе, как Redux может помочь свести к минимуму повторный рендеринг? Если контекст хранилища Redux изменяется, и все компоненты поддерева повторно визуализируются, то это то же самое, что и использование ванильного контекста, и пусть все компоненты являются потребителями.
4) Но, возможно, (3) выше не правильно ... потребители контекста и все поддерево перерисовываются ... просто так, Connect
HO C может не быть потребителем контекста, но может получить состояние магазина Redux - на самом деле, нет Context.Consumer
Что бы то ни было в инструменте React - как он работает?
5) Может быть, я нашел часть ответа: я продолжал видеть Memo
и Context.Provider
... в React / Redux , Является ли Memo
способом «остановить» повторный рендеринг от «перехода вниз по поддереву»? И тогда Context.Provider
вместе с Memo
походит на Connect
HO C, чтобы предоставить компоненту props
... но как это Connect
HO C получает состояние Redux, если это Memo
? (как в React.memo()
запомненном компоненте)? Если это сборка dev вместо производственной, то Memo
- это ConnectFunction
, а Context.Provider
находится под ним, а затем наш «подключенный» компонент находится под ним.
6 Кстати, я не уверен, что это сделано с помощью shouldComponentUpdate()()
: когда он возвращает false, все поддерево не перерисовывается, но если компонент наблюдает в хранилище Redux (используя store.subsribe()
), и изменяет реквизиты для дочернего элемента (нашего подключенного компонента), а затем выглядит так, как Redux может работать внутри. В качестве альтернативы, , если компонент Connect просто наследует от PureComponent, тогда shouldComponentUpdate()
просто поверхностно сравнивает состояние и поддерживает и возвращает false , если это просто изменение контекста. Это также приведет к тому, что целое поддерево не будет повторно отображаться. Я думаю, что это больше похоже на: если изменение контекста влияет на подключенный компонент внизу, тогда верните true
для shouldComponentUpdate()
и передайте соответствующий реквизит для подключенного компонента. В противном случае верните false
и оставьте подключенный компонент в покое.
Повторная визуализация здесь не означает обновление фактического DOM. Это просто означает вызов render()
компонентов класса или вызов компонента функции для получения виртуального дерева DOM, чтобы согласоваться с предыдущим виртуальным деревом DOM для поиска различий и, если таковые имеются, обновления фактического DOM.