Redux-thunk: `dispatch不是一个函数`。[英] Redux-thunk: `dispatch is not a function`

本文是小编为大家收集整理的关于Redux-thunk: `dispatch不是一个函数`。的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

因此,我对返回上述错误的操作有一个问题(请参阅附件图像),而不是按预期更新redux状态.我在这里忽略了什么?

ActionCreators.js

export function userToken(token) {
  console.log('userToken has been fired');
  return (dispatch) => {
    dispatch({
      type: 'Graphcool_Token',
      payload: token
    });
  } 
}

app.js

....
// Root Query
const allPostsCommentsQuery = graphql(All_Posts_Comments_Query, {
  options: {
    cachePolicy: 'offline-critical', 
    fetchPolicy: 'cache-first',
  },
});

export const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(actionCreators, dispatch);
}

export default compose(
  allPostsCommentsQuery,
  connect(mapDispatchToProps)
)(Main);

还原

var tokenDetails = function(state, action) {

  if (state === undefined) {
    state = [];
  }

  switch (action.type) {
    case 'Graphcool_Token':
      const newState = [action.payload];
      return newState;
    default:
      return state;
  }
}

export default tokenDetails;

loginuser.js

  signinUser: function(emailID, passwordID) {

    const email = emailID;
    const password = passwordID;

    this.props.client.mutate({
      mutation: signinUser_Mutation,
      variables: {
        email,
        password,
      },
      options: {
        cachePolicy: 'offline-critical', 
        fetchPolicy: 'cache-first',
      },
    })
    .then(this.updateStateLoginDetails)
    .catch(this.handleSubmitError);
  },

  updateStateLoginDetails: function({data}) {
    this.props.userToken(data.signinUser.token);
  },

store.js

import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, autoRehydrate} from 'redux-persist';
import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router'
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
import client from './apolloClient';
import localForage from 'localforage';

const middlewares = [thunk, client.middleware()];

const enhancers = compose(
    applyMiddleware(...middlewares),
    (typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' || process.env.NODE_ENV !== 'production') ? window.__REDUX_DEVTOOLS_EXTENSION__() : (f) => f,
    autoRehydrate(),
);

const store = createStore(
  rootReducer,
  {}, // initial state
  enhancers
);

// begin periodically persisting the store
persistStore(store, {storage: localForage});

export const history = syncHistoryWithStore(
  browserHistory, 
  store
);

if(module.hot) {
  module.hot.accept('./reducers/', () => {
    const nextRootReducer = require('./reducers/index').default;
    store.replaceReducer(nextRootReducer);
  });
}

export default store;

在此处输入图像说明

推荐答案

第一个参数您应该传递给connect是mapStateToProps,它是接收state和组件props的函数.需要它:

connect(null, mapDispatchToProps)(Main)

顺便说一句,一般来说,您不需要bindActionCreators ..通常返回对象就足够了,例如:

const mapDispatchToProps = {
  someActionName,
  someOtherAction,
}

本文地址:https://www.itbaoku.cn/post/1938069.html

问题描述

So, I'm having an issue with an action returning the above mentioned error (See attached image), instead of updating redux state as expected. What am I overlooking here?

actionCreators.js

export function userToken(token) {
  console.log('userToken has been fired');
  return (dispatch) => {
    dispatch({
      type: 'Graphcool_Token',
      payload: token
    });
  } 
}

App.js

....
// Root Query
const allPostsCommentsQuery = graphql(All_Posts_Comments_Query, {
  options: {
    cachePolicy: 'offline-critical', 
    fetchPolicy: 'cache-first',
  },
});

export const mapDispatchToProps = (dispatch) => {
  return bindActionCreators(actionCreators, dispatch);
}

export default compose(
  allPostsCommentsQuery,
  connect(mapDispatchToProps)
)(Main);

Reducer

var tokenDetails = function(state, action) {

  if (state === undefined) {
    state = [];
  }

  switch (action.type) {
    case 'Graphcool_Token':
      const newState = [action.payload];
      return newState;
    default:
      return state;
  }
}

export default tokenDetails;

LoginUser.js

  signinUser: function(emailID, passwordID) {

    const email = emailID;
    const password = passwordID;

    this.props.client.mutate({
      mutation: signinUser_Mutation,
      variables: {
        email,
        password,
      },
      options: {
        cachePolicy: 'offline-critical', 
        fetchPolicy: 'cache-first',
      },
    })
    .then(this.updateStateLoginDetails)
    .catch(this.handleSubmitError);
  },

  updateStateLoginDetails: function({data}) {
    this.props.userToken(data.signinUser.token);
  },

store.js

import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore, autoRehydrate} from 'redux-persist';
import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router'
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';
import client from './apolloClient';
import localForage from 'localforage';

const middlewares = [thunk, client.middleware()];

const enhancers = compose(
    applyMiddleware(...middlewares),
    (typeof window.__REDUX_DEVTOOLS_EXTENSION__ !== 'undefined' || process.env.NODE_ENV !== 'production') ? window.__REDUX_DEVTOOLS_EXTENSION__() : (f) => f,
    autoRehydrate(),
);

const store = createStore(
  rootReducer,
  {}, // initial state
  enhancers
);

// begin periodically persisting the store
persistStore(store, {storage: localForage});

export const history = syncHistoryWithStore(
  browserHistory, 
  store
);

if(module.hot) {
  module.hot.accept('./reducers/', () => {
    const nextRootReducer = require('./reducers/index').default;
    store.replaceReducer(nextRootReducer);
  });
}

export default store;

enter image description here

推荐答案

The first argument you should pass to connect is mapStateToProps, which is a function that receives the state and component props.. You should add null there if you don't need it:

connect(null, mapDispatchToProps)(Main)

BTW, generally speaking, you don't need bindActionCreators.. usually returning an object is enough, like:

const mapDispatchToProps = {
  someActionName,
  someOtherAction,
}