Actions must be plain object. Use custom middleware

白昼怎懂夜的黑 提交于 2020-01-21 11:44:08

问题


I am using Redux,redux-thunk with react. I am returning an object but still getting the error.

authActions.js

export function register(){
return (dispatch)=>{
    console.log("in register action");
    dispatch({type:'auth_user'})
}
}

calling this action from Register.js using connect and props

import  * as actions  from '../actions/authActions';

class RegisterForm extends React.Component{

handleRegister = (e)=>{
    e.preventDefault();
    console.log("inside handle register");
    console.log(this.props);
    this.props.register();
 }
}
var Register = connect(mapStateToProps,actions)(RegisterForm);

Error is

Actions must be plain objects. Use custom middleware for async actions.

EDIT 1

Implemented redux-thunk like below.

import thunk from 'redux-thunk';


const store = createStore(authReducer,applyMiddleware(
                        thunk, 
                        loggerMiddleware
                        ),window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__());


ReactDOM.render(
<Provider store={store}>
    <App />
</Provider>, 
document.getElementById('root'));

The code can be found on github using link https://github.com/abhikulshrestha22/social-network/tree/master/client


回答1:


You're using register from mapDispatchToProps:

this.props.register();

But it's just:

var Register = connect(mapStateToProps,actions)(RegisterForm);

So, calling register wouldn't work because it's in actions, actions.register:

var Register = connect(mapStateToProps,{register: actions.register})(RegisterForm);

Now, it should fix your issue.




回答2:


actions/index.js

// with thunk
export const register = () => dispatch => (
   dispatch({ type: 'auth_user' })
)

// without thunk
export const register = () => ({ type: 'auth_user' })

component/example.js

import React from 'react';
import { connect } from 'react-redux';
import { register } from '../actions';

const Example = ({ register }) => (
   <button onClick={register}>Register</button>
)

export default connect(null, { register })(Example);

reducers/index.js

const authReducer = (state=false, {type, payload}) => {
  switch(type) {
    case 'auth_user': return !state;
    default: return state;
  }
}



回答3:


There is nothing wrong with the current setup that you showed above.

I think your mapDispatchToProps may be the root cause of this problem.

You should declare your connect likes this

export default connect(
  null,
  { register }
)(Register);

instead of (if I'm not wrong)

const mapDispatchToProps = dispatch => {
  return {
    register: () => {
      dispatch(register());
    }
  };
};

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

That's my guess. Hope this may help you.




回答4:


handleRegister = (e) => {
  ...
  this.props.dispatch(register());
}

Of course:

  • Apply redux-thunk middleware
  • In Register.js import register() action
  • Connect Register component to Redux store with react-redux connect()

EDIT:

If this simplified code (without mapDispatchToProps) doesn't work, something is wrong with your question. Maybe your action payload contains something that's not a plain object? E.g. promise returned by axios?

Code Sandbox according to your question, everything seems to work fine: https://codesandbox.io/s/j2mny6rvnv



来源:https://stackoverflow.com/questions/52799687/actions-must-be-plain-object-use-custom-middleware

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!