带有 React.memo 的 useSelector 与连接

She*_*hid 10 redux react-redux react-hooks

从链接中引用。 https://react-redux.js.org/next/api/hooks#performance

我所理解的useSelector钩子的好处是避免包装地狱。由于HOC的使用,包装地狱正在发生。如果一定要使用HOC与由于性能比较的原因,这将是更好的方法来简单地使用HOC呢?因为在任何情况下,我们都将不得不置身于包装器的地狱中。如果地狱不是那么将是。connect React.memo useSelectorconnect connectReact.memo

任何人请解释React.memoover的好处connect

Ole*_*hai 21

好吧,首先,虽然 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);
Run Code Online (Sandbox Code Playgroud)

这是呈现的结构:

在此处输入图片说明

我们可以看到连接的内容被渲染得更深。

其次,文档说:

默认情况下,useSelector() 将在调度 action 后运行选择器函数时对所选值进行引用相等比较,并且只有在所选值更改时才会导致组件重新渲染。但是,与 connect() 不同,useSelector() 不会阻止组件由于其父级重新渲染而重新渲染,即使组件的 props 没有更改。

这意味着当商店的不相关部分发生变化时,不会重新渲染 useSelector 的组件。这是优化中最重要的部分。现在是否使用 React.memo 进行优化完全取决于您的决定,并且在大多数情况下,根本不需要。我们仅在组件渲染成本非常高的情况下使用 React.memo。

总而言之,需要连接包装器才能连接到商店。使用 useSelector 我们不必再包装了。当我们需要优化一些重组件时,我们仍然需要在极少数情况下使用 React.memo 进行包装。React.memo 的工作也是由 connect 完成的,但在大多数情况下,它是过早的优化。


Kle*_*leo 5

我很长一段时间以来一直试图得到答案,但得到的答案并不明确。虽然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)
Run Code Online (Sandbox Code Playgroud)

并将其添加到您的选择器中,例如:const object = useSelector(state => state.object, makeGetObject);当我试图了解它的底部时,我创建了这个codesandbox(检查组件上的注释WithUseSelector):useSelector vs connect()

  • 不,你的例子展示了完全不同的事情。在评论您的回复之前我已经亲自证明了这一点。所以请不要打扰。WithUseSelector 组件正在重新渲染的原因是因为父组件(App)正在重新渲染。另一方面connect HOC也有其性能优化。如果我们想要获得 HOC 提供的相同好处,我们必须在使用 useSelector 时添加 React.useMemo。您可以查看文档(https://react-redux.js.org/api/hooks#performance) (2认同)