reactjs - Next Redux Wrapper 中的水合物作用是什么?

标签 reactjs redux react-redux next.js next-redux-wrapper

最近我开始使用 Next.js,我对 next-redux-wrapper 包有疑问。我不太了解 HYDRATE 操作。所以我想知道它具体是什么,它有什么用,什么时候推出。

因为目前我唯一真正理解的是它与 getServerSideProps 函数一起使用,以允许在呈现页面之前“加载”商店。

但是还有很多问题没有答案,例如:

export const getServerSideProps = wrapper.getServerSideProps(store => () => {
  store.dispatch(getTasks())
})

在这种情况下,我想知道调度 getTasks 操作的意义何在,因为它将播放 HYDRATE 操作。或者,为什么要使用 next-redux-wrapper 包而不是仅使用普通的 getServerSideProps 函数,我们可以在其中通过简单地导入商店来调度 getTasks 操作?

这可能看起来很愚蠢,但由于这方面的资源很少,而且我也没有经验,再加上我是法国人。所以我无法理解包装器的用处。

考虑到我的困难,如果能给我提供明确的答案,我将不胜感激。

最佳答案

您需要在使用 Redux 的 Next.js 服务器上从一开始就意识到为什么需要它。

您的商店实际上有两个不同的实例

React-wise on Next.js 有两种场景:SSR 和 CSR。请记住,Next.js 无法向客户端发送任何比可序列化 JSON 更复杂的 javascript 对象,这意味着客户端拥有的商店实例不是您初始化并放入 React 应用程序的实例服务器端。

比如会有两个不同的StoreInstance,一个在服务端,一个在客户端。

// pages/_app.js
import StoreInstance from ...

export default function App({ Component }) {
  return (
    <Provider store={StoreInstance}>
      <Component />
    </Provider>
  );
}

因此,如果您在服务器端唯一生命周期内初始化 StoreInstance 的某些状态,例如 getServerSideProps,您只会对服务器端实例执行此操作,因此是客户端实例在初始页面加载时不会有相同的状态。

有关更多信息,这会导致 Next.js 制作的标记与 React.js 制作的标记之间的差异,后者派生自 Next.js 的 hydration。在初始页面加载时。 (并且 Next.js 检测到这种差异并发出警告:Warning: Did not expect server HTML to contain the text node)

Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration)

您的代码将在 Next.js 上的 SSR 和 CSR 上运行

如果您在像 _app 这样同时运行在服务器端和客户端的生命周期内初始化 StoreInstance 的一些状态会怎么样?好吧,当您通过 Link(派生 CSR)导航同一页面时,您会遇到警告 Warning: Cannot update a component ('Page') while rendering a different component ('App '),这似乎是由竞争条件引起的,如 next-redux-wrapper 作者指出:

It is highly recommended to use pages/_app to wrap all pages at once, otherwise due to potential race conditions you may get Cannot update component while rendering another component

什么是HYDRATE Action

现在您看到您需要让两个存储实例具有相同的状态(在初始加载时),同时遵守竞争条件。而 next-redux-wrapper 通过 hydrating 服务器端实例的状态到客户端实例中来实现这一点(这种水化与 Next.js 中的概念相同).因为它以与 Redux 相同的工作方式实现了 hydration,所以它必须将操作的类型设置为 HYDRATE,这样您就可以将它与 Redux 的常规更新区分开来。

为什么模块作者选择这种方式让它工作?他说这是因为如果您只是替换 CSR 上的商店,即使没有必要,Redux 也会重新渲染所有内容。

In Next.js example https://github.com/vercel/next.js/blob/canary/examples/with-redux/store.js#L55 store is being replaced on navigation. Redux will re-render components even with memoized selectors (createSelector from recompose) if store is replaced: https://codesandbox.io/s/redux-store-change-kzs8q, which may affect performance of the app by causing a huge re-render of everything, even what did not change. This library makes sure store remains the same.

何时调度HYDRATE 操作

每当您的 _app 收到请求时,无论您是否在服务器端将某些内容发送到您的商店,都会使用商店的初始状态发送操作。

关于reactjs - Next Redux Wrapper 中的水合物作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71265315/

相关文章:

reactjs - 如何在 React 状态对象数组中设置属性

javascript - 使用名称中的变量值访问 redux 存储

javascript - 在 React 和 Redux 中创建动态按钮

javascript - Uncaught Error : Parse Error: Line 13: Unexpected identifier

javascript - 让文件= event.target.files;没有文件

javascript - Webpack + React : Webpack builds from my node_modules folder in correct order in one place, 以及其他地方的错误顺序

javascript - 将 Promise.all 与 React-Redux-Thunk 一起使用的更好/正确方法是什么?

javascript - × TypeError : Cannot read properties of undefined (reading 'getState' )

reactjs - 如何在 React Material UI 中为属性添加 css

reactjs - 如何确保 Redux Saga 中数据不会加载两次?