Next.JS Redux 调度在 getStaticProps() 中不起作用
Posted
技术标签:
【中文标题】Next.JS Redux 调度在 getStaticProps() 中不起作用【英文标题】:Next.JS Redux dispatch not working in getStaticProps() 【发布时间】:2021-03-17 11:13:12 【问题描述】:我对 Next.JS 还很陌生,我正在尝试使用我的 Next.JS 应用程序设置 Redux。现在我的页面应该显示我从 API 调用的帖子列表。当我从useEffect()
调度以将数据填充到我的页面时,页面呈现完美,但getStaticProps()
或getServerSideProps()
无法正常工作!
这里有一些代码可以让你知道我到目前为止所做的事情:
store.js
import useMemo from 'react'
import createStore, applyMiddleware from 'redux'
import composeWithDevTools from 'redux-devtools-extension'
import thunk from 'redux-thunk'
import rootReducer from './reducers/rootReducer'
const initialState =
const middlewares = [thunk]
let store
function initStore(preloadedState = initialState)
return createStore(
rootReducer,
preloadedState,
composeWithDevTools(applyMiddleware(...middlewares))
)
export const initializeStore = (preloadedState) =>
let _store = store ?? initStore(preloadedState)
if (preloadedState && store)
_store = initStore(
...store.getState(),
...preloadedState,
)
store = undefined
if (typeof window === 'undefined') return _store
if (!store) store = _store
return _store
export function useStore(initialState)
const store = useMemo(() => initializeStore(initialState), [initialState])
return store
action.js
export const fetchPosts = () => async dispatch =>
const res = await axios.get('https://jsonplaceholder.typicode.com/posts')
dispatch(
type: FETCH_POSTS,
payload: res.data
)
_app.js
import Provider from 'react-redux'
import createWrapper from 'next-redux-wrapper'
import useStore from '../redux/store'
export default function MyApp( Component, pageProps )
const store = useStore(pageProps.initialReduxState)
return (
<Provider store=store>
<Component ...pageProps />
</Provider>
)
这些是基本 redux 设置所需的文件。一旦我的商店建立起来,我将我的应用程序包裹在Provider
周围,我最初想使用useEffect()
挂钩来填充在我的index.js
文件中呈现的组件上的数据。
component.js
import useEffect from 'react'
import useDispatch, useSelector from 'react-redux'
import fetchPosts from '../redux/actions/postsAction'
const Posts = () =>
const dispatch = useDispatch()
const items = useSelector(state => state.posts)
useEffect(() =>
dispatch(fetchPosts())
, [])
return (
<div className="">
<h1>Posts</h1>
items.map(post =>
return (<div key=post.id>
<h3>post.title</h3>
<p>post.body</p>
</div>)
)
</div>
)
export default Posts
这很完美!我所有的帖子都显示在组件内。当我试图通过服务器端渲染(甚至 SSG)实现相同的行为时,就会出现问题。我想在预渲染阶段填充数据,但由于某种原因,应该保存所有数据的 items 数组是空的,基本上意味着调度程序从未被调用!这是困扰我的一段代码(与之前的代码完全相同,但这次我使用的是getStaticProps()
而不是useEffect()
):
component.js
import useEffect from 'react'
import useDispatch, useSelector from 'react-redux'
import fetchPosts from '../redux/actions/postsAction'
const Posts = ( items ) =>
return (
<div className="">
<h1>Posts</h1>
items.map(post =>
return (<div key=post.id>
<h3>post.title</h3>
<p>post.body</p>
</div>)
)
</div>
)
export async function getStaticProps()
console.log('Props called')
const dispatch = useDispatch()
const items = useSelector(state => state.posts)
dispatch(fetchPosts())
console.log(items)
return props: items
export default Posts
通过运行此程序,我收到一个错误,即项目为空!请帮帮我,我不知道这里出了什么问题。
【问题讨论】:
【参考方案1】:好吧,我自己解决了这个问题,但我忘了发布答案,我的错!
这里的问题真的很简单,钩子在功能组件之外不起作用!
【讨论】:
【参考方案2】:我认为,在getStaticProps
内部,只需调用 API 或从 DB 获取数据并将其作为道具返回给 pages/index.js
(您想要的任何组件),在此组件内部,我们可以从 getStaticProps
获取数据作为道具。
我们还可以使用 react-redux 的 useDispatch
将其设置为全局状态。之后,我们可以使用 redux mapStateToProps
调用任何组件。这是我的解决方案。
【讨论】:
以上是关于Next.JS Redux 调度在 getStaticProps() 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Next js 应用刷新时,useEffect 不调度 redux saga 动作并更新状态
redux thunk 中的 getState() 是不是会更改实际状态