如何使用 next.js 、应用程序路由器从服务器组件初始化 redux 存储

问题描述 投票:0回答:1

我正在使用 Next.js 13、React 和 Redux 来管理状态。

我的目标是在服务器端加载初始数据并将其显示在客户端。我认为这将是 Redux 和 Next.js 的标准方法,但我还没有找到实现它的方法。

这是我的理解:

Redux 存储设置两次:一次在服务器端,另一次在客户端。我以为我可以简单地在服务器端获取数据,使用调度函数进行初始化,然后让客户端加载数据。但问题是服务器端组件无法使用调度或操作存储数据。

Redux 文档指出,React 服务器组件 (RSC) 不应读取或写入 Redux 存储,因为它们无法使用钩子或上下文,并且不意味着是有状态的。那么,我们如何加载初始数据呢?初始数据是否异常?如果是这样,我们如何更新这个初始数据?

这是我的代码,这是RSC

ContactListServerComponent.tsx

import ContactList from "@/component/Contacts/page"
import {
  getInitialContactsData,
  initializeContact,
} from "@/lib/features/contacts/contactSlice"
import { makeStore } from "@/lib/store"
import styles from "./contacts.module.scss"

const ContactListPage = async () => {
  const initialData = await getInitialContactsData()
  console.log("server component")
  const store = makeStore()
  store.dispatch(initializeContact(initialData))
  return (
    <div className={styles.container}>
      <h1>Contacts</h1>
      <ContactList />
    </div>
  )
}

export default ContactListPage

这是客户页面(联系人列表)

const ContactList = () => {
  const dispatch = useAppDispatch()
  const contacts = useSelector((state: RootState) => state.contacts)
  const [filter, setFilter] = useState<string | null>(null)
  useEffect(() => {
    dispatch(getContacts())
  }, [dispatch] 

  .... etc

我有一个服务器组件(ContactListServerComponent.tsx),我试图在其中获取和分派初始数据。然后,我有一个客户端组件 (ContactList),目前我正在使用

useEffect
来获取数据,这并没有充分利用 SSR 的优势。我不确定如何实现我的想法,以在服务器组件而不是客户端组件上获取初始数据。

我想知道如何从服务器组件上的 API 加载数据并将其传递给客户端组件。

reactjs typescript next.js redux
1个回答
0
投票

有点晚了,但如果你想避免 prop 钻取,你可以简单地首先在页面或布局中加载初始数据,然后将其传递给客户端组件,该组件将获取初始数据并将其分派到客户端 redux 存储中:

'use client';

const InitialDataLoader = ({initialData}: any) => {
    useEffect(() => {
        store.dispatch(
            actions.setState({key: 'initialData', value: initialData}),
        );
    }, []);
    return null;
}

另一种选择是使用 React Context,例如:


interface ContextProps {initialData: any}
const InitialDataContext = createContext<ContextProps | undefined>(undefined);
export const InitialDataProvider = ({
    children,
    initialData,
}: {
    children: ReactNode,
} & ContextProps) => {
    return (
        <InitialDataContext.Provider value={{initialData}}>
            {children}
        </InitialDataContext.Provider>
    );
};

export const useInitialData = () => {
    const context = useContext(InitialDataContext);
    if (!context) {
        throw new Error('useInitialData must be used within an InitialDataProvider');
    }
    return context.initialData;
};

然后在您要获取初始数据的服务器组件中使用它:

<InitialDataProvider initialData={initialData}>
  {children}
</InitialDataProvider>

任何服务器端重新验证也会更改上下文中提供的数据。

© www.soinside.com 2019 - 2024. All rights reserved.