【问题标题】:NextJS and Redux : Cannot use thunk middlewareNextJS 和 Redux:不能使用 thunk 中间件
【发布时间】:2020-11-29 21:54:32
【问题描述】:

我正在尝试使用 thunk 对 api 进行异步调用,但我仍然收到错误消息: 未处理的运行时错误:操作必须是普通对象。使用自定义中间件进行异步操作。

这是我的自定义 _app 组件

// to connect redux with react 
import { Provider } from 'react-redux';
import { createWrapper } from 'next-redux-wrapper';

import { createStore, applyMiddleware } from 'redux';
import reducers from '../redux/reducers';
import thunk from 'redux-thunk';

const store = createStore(reducers, applyMiddleware(thunk));

const AppComponent = ({ Component, pageProps }) => {
    return (
        <Provider store={store}>
            <Component {...pageProps} />
        </Provider>
    )
}

AppComponent.getInitialProps = async (appContext) => {
    let pageProps = {};
    if (appContext.Component.getInitialProps) {
        pageProps = await appContext.Component.getInitialProps(appContext.ctx);
    };
    return { ...pageProps }
}

// returns a new instance of store everytime its called
const makeStore = () => store;
const wrapper = createWrapper(makeStore);

export default wrapper.withRedux(AppComponent);

这是登陆页面,我将在其中分派动作创建者:

import { connect } from 'react-redux';
import { fetchPosts } from '../redux/actions';
import { bindActionCreators } from 'redux';
import { useEffect } from 'react';
import Link from 'next/link';

const LandingPage = (props) => {
    useEffect(() => {
        props.fetchPosts();
    }, [props]);

    return <div>
        <Link href="/">
            <a>Home</a>
        </Link>
    </div>
}

LandingPage.getInitialProps = async ({ store }) => {
    store.dispatch(await fetchPosts());
}

const mapDispatchToProps = (dispatch) => {
    return {
        // so that this can be called directly from client side
        fetchPosts: bindActionCreators(fetchPosts, dispatch)
    }
}


export default connect(null, mapDispatchToProps)(LandingPage);

行动:

import api from '../../api';

// returning a function and dispatching manually to make use of async await to fetch data
export const fetchPosts = async () => async (dispatch) => {
    const response = await api.get('/posts');
    dispatch({
        type: 'FETCH_POSTS',
        payload: response
    });
};

遗憾的是,GitHub Next + Redux 示例NEXT+REDUX 对我来说理解起来真的很复杂,因为我是第一次使用 NextJS 尝试 redux。 而且每篇博文都有自己的做法,但似乎没有任何效果。

我不想让它变得更复杂。如果有人能帮助我为什么会出现此错误,我将不胜感激?

【问题讨论】:

    标签: reactjs redux react-redux next.js


    【解决方案1】:

    当你调用这个时,问题不在于 next.js :

    LandingPage.getInitialProps = async ({ store }) => {
        store.dispatch(await fetchPosts());
    }
    

    fetchPosts 这里是一个 Promise 并且 dispatch dispatch action 必须是一个普通的对象,所以要解决这个 remove async word from it like this:

    export const fetchPosts = () => async (dispatch) => {
        const response = await api.get('/posts');
        dispatch({
            type: 'FETCH_POSTS',
            payload: response
        });
    };
    

    如果你想等待 api 响应,你需要像这样在组件中调用它:

    const App= ()=>{
    const dispatch = useDispatch()
    useEffect(() => {
     const fetch = async()=>{
    try{
        const response = await api.get('/posts');
        dispatch({
            type: 'FETCH_POSTS',
            payload: response
        });
    }
    catch(error){
    throw error
    }
     }
     fetch()
        }, []);
    
    return ....
    }
    

    【讨论】:

    • 这就是我使用 Redux Thunk 来避免这种情况的原因。
    • 是的,redux thunk 是在 redux 操作到达 reducer 之前拦截它们的中间件。他们处理副作用但不返回承诺它返回一个返回动作的func调用thunk。但如果你想等待 api 检查编辑的答案
    • 我不能绕过它,而是在 getInitialProps 中调度操作吗?这不会引发任何错误,我也不必在 useEffect 或 ComponentDidMount() 中调度任何操作。因为这将通过 GetInitialProps 方法在每次渲染时分派。对吗?
    • 是的,如果您从行动中返回承诺,请检查此答案:stackoverflow.com/questions/54054887/…
    猜你喜欢
    • 2019-01-01
    • 2017-08-23
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 2020-09-21
    相关资源
    最近更新 更多