Использовать выбор с React.memo против подключения

Ссылаясь на ссылку. https://react-redux.js.org/next/api/hooks

в чем я понимаю пользу useSelector крючок, это чтобы избежать обертки ада. Обёртывание ада происходит из-за использования connect HOC. Если мы должны использовать React.memo HOC с useSelector По причине производительности, лучше было бы просто использовать connect HOC вместо этого? Потому что в любом случае мы должны быть в аду фантиков. Если ад не connect тогда будет React.memo,

Любой, пожалуйста, объясните пользу React.memo над connect,

3 ответа

Решение

Ну, во-первых, достаточно интересно, хотя React.memo является HOC, он не создает ту же вложенность, что и connect. Я создал тестовый код:

import React from "react";
import ReactDOM from "react-dom";
import {connect, Provider} from 'react-redux'
import { createStore } from 'redux'
import "./styles.css";

const MemoComponent = React.memo(function MyMemo() {
  return <div>Memo</div>;
});

const ConnectedComponent = connect(null,null)(function MyConnected() {
  return <div>ReduxConnectComponent</div>;
})

const store = createStore(()=>{},{})


function App() {
  return (
    <Provider store={store}>
      <MemoComponent />
      <ConnectedComponent/>
    </Provider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

И вот структура представлена:

Мы видим, что контент для подключения отображается глубже.

Во-вторых, документы говорят:

по умолчанию useSelector() будет выполнять сравнение ссылочного равенства выбранного значения при запуске функции селектора после отправки действия и будет вызывать повторный рендеринг компонента только при изменении выбранного значения. Однако, в отличие от connect(), useSelector() не предотвращает повторную визуализацию компонента из-за его родительской повторной визуализации, даже если реквизиты компонента не изменились.

это означает, что компонент, использующий Selector, не будет перерисован при изменении несвязанных частей магазина. И это самая важная часть оптимизации. Оптимизация с помощью React.memo или нет сейчас полностью зависит от вашего решения, и в большинстве случаев это просто не нужно. Мы используем React.memo только в тех случаях, когда компонент очень дорог в рендеринге.

Подводя итог, необходимо подключить обертку для подключения к магазину. С useSelector нам больше не нужно оборачиваться. Нам все еще нужно обернуть React.memo в тех редких случаях, когда нам нужно оптимизировать некоторые тяжелые компоненты. Работа React.memo также была выполнена с помощью connect, но в большинстве случаев это была преждевременная оптимизация.

Я довольно долго пытался получить ответ, но ответы, которые я получил, были нечеткими. Хотя теория в документации Redux не сложна:useSelector использует строгое равенство ===и connect для определения использует поверхностное равенство. Таким образом, в обоих случаях, если вы "вытаскиваете" примитивное значение из своего состояния Redux (число, строка, логическое значение), вы получите тот же результат. Если значения не изменились, ни один из компонентов не будет перерисован. Если вы "вытягиваете" непримитивы (массивы или объекты) и значения не изменились для обоих случаев (useSelector, connect), то компонент, который используетuseSelector все равно будет перерисовывать, как конечно [] === [] всегда будет ложным, поскольку они ссылаются на разные массивы, где, как connected компонент НЕ будет повторно отображать. Теперь, чтобы сделатьuseSelector вести себя аналогично и не перерисовывать, вы можете сделать это:const object = useSelector(state => state.object, shallowEqual) Вы можете импортировать shallowEqual от react-redux. Или, в качестве альтернативы, используйте мемоизированную версию этого состояния, используяreselect библиотека:

const makeGetObject = () => createSelector(state => state.object, object => object)

и добавьте его в свой селектор, например: const object = useSelector(state => state.object, makeGetObject); Я создал этот ящик с кодами, когда пытался разобраться в нем (проверьте комментарии в WithUseSelectorкомпонент): useSelector vs connect()

Я просто настроил хук useSelector, чтобы избежать этого, и он отлично работает.

Другие вопросы по тегам