Next.js中在getStaticProps调用Redux Thunk无法使用Hook的问题咨询
核心问题原因
getStaticProps 是Next.js在服务端构建/增量更新阶段执行的Node侧函数,不属于React组件生命周期,不支持调用任何React Hook,所以你使用useDispatch的写法本身就不成立。
先修复Slice代码的错误
你当前的Slice存在三处逻辑错误,会导致即使在组件内Dispatch thunk也无法正常触发状态更新:
extraReducers绑定的回调关联的是未使用的空对象getData,实际应该关联你创建的异步thunkfetchDatarejected回调没有接收state参数,运行时会抛错- 状态文字拼写错误:
Sucsess改为Success
修复后的Slice代码:
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; // 抽离公共请求逻辑,方便服务端/客户端两边复用 export const requestCoinData = async (url) => { const res = await fetch(url); return res.json(); }; export const fetchData = createAsyncThunk( "fetchCoinData", async (url, thunkApi) => { return await requestCoinData(url); } ); const initialState = { data: [], status: null, }; export const dataSlice = createSlice({ name: "datafetch", initialState, extraReducers: { [fetchData.pending]: (state) => { state.status = "Loading!"; }, [fetchData.fulfilled]: (state, { payload }) => { state.data = payload; state.status = "Success!"; }, [fetchData.rejected]: (state) => { state.status = "Failed"; }, }, }); export default dataSlice.reducer;
可行实现方案
推荐方案(逻辑最简单,性能最优)
在getStaticProps中直接调用公共请求方法拿数据,返回给页面当props,再在页面组件初始化时将数据存入Redux全局,避免重复发请求:
import React, { useEffect } from "react"; import { useDispatch } from "react-redux"; import BasicCard from "../../Components/UI/Cards/BasicCard"; import { UsersIcon } from "@heroicons/react/outline"; import { fetchData, requestCoinData } from "../../redux/slice/DataSlice"; const Cardano = (props) => { const dispatch = useDispatch(); const { theData } = props; // 组件挂载时将预取的数据存入Redux全局 useEffect(() => { if (theData) { // 直接用预取结果更新Redux,无需重复请求 dispatch(fetchData.fulfilled(theData)); } }, [theData, dispatch]); return ( <div> <h1>Header</h1> </div> ); }; export async function getStaticProps(context) { const priceQuery = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Ccardano%2Cethereum&vs_currencies=USD"; // 直接调用公共请求方法拿数据 const theData = await requestCoinData(priceQuery); return { props: { theData, }, // 可按需添加revalidate配置开启增量静态再生 }; } export default Cardano;
内容的提问来源于stack exchange,提问作者NoobAndroid
相关产品推荐
相关产品推荐

