簡體   English   中英

Next.JS Redux 調度在 getStaticProps() 中不起作用

[英]Next.JS Redux dispatch not working in getStaticProps()

我是 Next.JS 的新手,我試圖用我的 Next.JS 應用程序設置 Redux。 現在我的頁面應該顯示我從 API 調用的帖子列表。當我從useEffect()調度以將數據填充到我的頁面時,頁面呈現完美,但是getStaticProps()getServerSideProps()根本不起作用!

這里有一些代碼可以讓您了解我到目前為止所做的事情:

商店.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
}

動作.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文件中呈現的組件上的數據。

組件.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)實現相同的行為時出現問題,我想在預渲染階段填充數據,但由於某種原因,應該保存所有數據的項目數組是空,基本上意味着調度員從未被調用過! 這是困擾我的一段代碼(與之前的代碼完全相同,但這次我使用getStaticProps()而不是useEffect() ):

組件.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

通過運行這個,我得到一個錯誤,項目是空的,請幫助我。 我不知道這里出了什么問題。

好吧,我自己解決了這個問題,但我忘了發布答案,我的錯!

這里的問題真的很簡單,鈎子在功能組件之外不起作用!

我認為,在getStaticProps內部只需調用 API 或從 DB 獲取數據並將其作為道具返回給pages/index.js (您想要的任何組件),在該組件內部,我們可以從getStaticProps獲取數據作為道具。

我們也可以使用useDispatch的 useDispatch 將其設置為全局 state。 之后,我們可以使用 redux mapStateToProps調用任何組件。 這是我的解決方案。

如果有人遇到這個問題,這可能是一個解決方案,

import React from 'react';
import {useSelector} from 'react-redux';
import {wrapper} from '../store';

export const getStaticProps = wrapper.getStaticProps(store => ({preview}) 
=> {
console.log('2. Page.getStaticProps uses the store to dispatch things');
store.dispatch({
type: 'TICK',
payload: 'was set in other page ' + preview,
 });
});

// you can also use `connect()` instead of hooks
const Page = () => {
const {tick} = useSelector(state => state);
return <div>{tick}</div>;
};


export default Page;

從這里得到它: https://github.com/kirill-konshin/next-redux-wrapper

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM