Redux在NextJS 13(approuter)-模式最小化'使用客户端'

doinxwow  于 2023-11-18  发布在  其他
关注(0)|答案(1)|浏览(86)

我是NextJS的新手。看到了很多教程,包括来自vercel自己的这个-https://github.com/vercel/next.js/tree/canary/examples/with-redux
他们有标准的模式-
1.创建Redux Provider

"use client";
    import {Provider} from "react-redux"
    import {store} from "./store";
    import React from "react";
    
    export default function ReduxProvider({children}: { children: React.ReactNode }) {
        return <Provider store={store}>{children}</Provider>;
    
    };

字符串
1.然后在需要redux的组件中使用它,但是需要为该组件声明**'use client'**

'use client'
    import { useDispatch } from "react-redux";
    import {increment, decrement} from "./counterSlice";
    import Button from 'react-bootstrap/Button';
    
    const Counter = () => {
      const dispatch = useDispatch();
      return (
        <div>
          <Button onClick={() => { dispatch(increment()); }}> + </Button>
          <Button onClick={() => { dispatch(decrement()); }}> - </Button>
        </div>
        );
    };
    export default Counter;


这是一个非常简单/简化的示例,实际上,这些组件可能涉及更多。
问题是-这是否会因为我们使用Redux而破坏NextJS中SSR的目的,因为所有标记为use client的组件都不会生成SSR。
相反,将CSR组件减少到基于redux的组件中,其中包含use client,以便可以进行redux调用,然后调用生成SSR的非客户端(SSR)组件,这是否是一个正确的模式。
让客户端组件具有Redux调用

'use client'
    import {increment, decrement} from "./counterSlice";
    import {CounterSSR} from './CounterSSR'
    
    const CounterClient = () => {
      return (
        <CounterSSR
            onIncrement={() => { dispatch(increment()); }}
            onDecrement={() => { dispatch(decrement()); }} />
        );
    };
    export default CounterClient;


然后具有如下的SSR分量CounterSSR

import Button from 'react-bootstrap/Button';
    
    const CounterSSR = (props) => {
      return (
        <div>
          <Button onClick={props.onIncrement}> + </Button>
          <Button onClick={props.onDecrement}> - </Button>
        </div>
        );
    };
    export default CounterSSR;


问题是,这样一来,我最终得到了一个组件的两个副本,一个是逻辑(redux调用),另一个是用于渲染的“哑”UI组件。
对此有何建议?

v1l68za4

v1l68za41#

不使用钩子,您可以直接使用存储引用(老方法)来分派动作

'use client'
import store from "<path to redux store>";
import {increment, decrement} from "./counterSlice";
import Button from 'react-bootstrap/Button';

const Counter = () => {
  return (
    <div>
      <Button onClick={() => { store.dispatch(increment()); }}> + </Button>
      <Button onClick={() => { store.dispatch(decrement()); }}> - </Button>
    </div>
    );
};
export default Counter;

字符串
即使你使用上面的代码,你仍然需要声明use client,因为你使用的是事件处理程序(onClick)来执行操作,这只允许在客户端组件中使用。
如果你从store中阅读数据,你可以直接使用store来访问状态,而不是使用useSelector钩子。

相关问题