2017-05-24 118 views
3

我得到类似 的错误操作必须是普通对象。使用自定义中间件进行异步动作 ,同时使用reactx。我开发一个应用程序与登录功能。这是我的代码。使用Redux时,操作必须是普通对象

部件

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 
import {connect} from 'react-redux'; 
import {bindActionCreators} from 'redux'; 
import Paper from 'material-ui/Paper'; 
import TextField from 'material-ui/TextField'; 
import RaisedButton from 'material-ui/RaisedButton'; 
import * as AuthActions from '../../actions/AuthAction'; 
import {blueGrey50,lightBlue500} from 'material-ui/styles/colors'; 

const style = { 
    height: 350, 
    width: 370, 
    marginLeft: 80, 
    marginRight: 380, 
    marginTop: 80, 
    marginBottom: 50, 
    textAlign: 'center', 
    display: 'inline-block', 
    backgroundColor: blueGrey50, 
    paddingTop: 20, 
}; 

const style1 = { 
    color: lightBlue500 
}; 

const style2 = { 
    margin: 12, 
}; 

class Login extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
     email: '', 
     password: '' 
     }; 

    } 

    singin=()=>{ 
     console.log('signing in'); 
     this.props.SigninActions.signIn({email:this.state.email,password:this.state.password}); 
     this.setState({email: '',password: '',loading:true}); 
     console.log('done sending to actions'); 
    } 

    render() { 
     return (
     <div style={{backgroundImage: "url(" + "https://addmeskype.files.wordpress.com/2015/09/d62cb-teenagers-offlinle-online.jpg" + ")", 
        width:1301, height:654}}> 
      <Paper style={style} zDepth={2}> 
      <h1 style={style1}><center>Sign In</center></h1> 
      <TextField hintText="Email" floatingLabelText="Email" onChange={e=>{this.setState({email:e.target.value})}}/> 
      <TextField hintText="Password" floatingLabelText="Password" type="password" onChange={p=>{this.setState({password:p.target.value})}}/> 
      <br/><br/> 
      <RaisedButton label="Sign In" primary={true} style={style2} onTouchTap={this.singin}/> 
      </Paper> 
      { 
      (this.props.isError)? <span>Email or Password combination is wrong!</span> : <div>No errors</div> 
      } 
     </div> 
    ); 
    } 
} 

Login.PropTypes = { 
    isError: PropTypes.bool, 
    SigninActions: PropTypes.object 
} 

const mapStateToProps = (state,ownProps) => { 
    return { 
    isError: state.isError 
    } 
} 

const mapDispatchToProps = (dispatch) => { 
    return { 
    SigninActions:bindActionCreators(AuthActions,dispatch) 
    }; 
} 

export default connect(mapStateToProps,mapDispatchToProps)(Login); 

操作

import axios from 'axios'; 
import jwtDecode from 'jwt-decode'; 
import { SIGN_UP_REQUEST, SIGN_IN_REQUEST, GET_USER_DETAILS, UPDATE_USER_DETAILS } from '../constants/user'; 

export const getUserDetails=(email)=>{ 

    axios.get('http://localhost:3030/user', 
     email 
    ) 
     .then((data)=>{ 
     console.log(data); 
     return ({ 
      type: GET_USER_DETAILS, 
      user:data.data 
     }); 
     }) 
     .catch((error)=>{ 
     console.log('err', error); 
     }); 
} 


export const updateUserDetails=(user)=>{ 

    axios.put('http://localhost:3030/user', 
     user 
    ) 
     .then((data)=>{ 
     console.log(data); 
     return ({ 
      type: UPDATE_USER_DETAILS, 
      user:data.data 
     }); 
     }) 
     .catch((error)=>{ 
     console.log('err', error); 
     }); 
} 

减速器

import { SIGN_UP_REQUEST, SIGN_IN_REQUEST} from '../constants/user'; 

const initialState = { 
    loading: false, 
    isError: false 
}; 


export default function User(state = initialState, action) { 
    switch (action.type) { 
    case SIGN_UP_REQUEST: 
     return Object.assign({},state,{isError:action.data.isError}); 

    case SIGN_IN_REQUEST: 
     return Object.assign({},state,{isError:action.data.isError}); 

    default: 
     return state; 
    } 
} 

Rootreducer

import { combineReducers } from 'redux'; 
import ChatReducer from './ChatReducer'; 
import UserReducer from './UserReducer'; 

export default combineReducers({ 
    chat: ChatReducer, 
    user: UserReducer 
}) 

商店

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


export default() => { 
    return createStore(RootReducer, 
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()); 
} 

浏览器会显示错误的 enter image description here

如何解决这个问题?我相当新还原。

回答

2

香草终极版只处理纯对象的动作,例如

{ type: SOME_ACTION, ...parameters }

返回同步

如果您想从操作创建者(或者在这种情况下处理异步操作)返回Promises或真的除了普通对象之外的其他任何东西,则需要使用中间件如redux-thunk进行研究。

看到这一点:How to dispatch a Redux action with a timeout?

编辑:

的问题是一种双重的的:

第一:

export const getUserDetails = (email) => { 
    axios.put('http://localhost:3030/user', user) .then((data) => { 
     return { 
      type: UPDATE_USER_DETAILS, 
      user:data.data 
     }; 
    }); 
}); 

你返回一个在亲的行动mise(axios.put),但是你没有回复承诺 - javascript不能正常工作。 return,在这种情况下,仅限于最近的父范围;在这种情况下,承诺的主体。刚刚给出您目前的状态,getUserDetails操作创建者的返回类型为undefined

// this is still technically *wrong*, see below 
export const getUserDetails = (email) => { 
    // notice the return on the next line 
    return axios.put('http://localhost:3030/user', user) .then((data) => { 
     return { 
      type: UPDATE_USER_DETAILS, 
      user:data.data 
     }; 
    }); 
}); 

返回Promise<Action>这仍然不能真正解决您的问题。

第二: 当终极版-的thunk工作,你换你的行动,这样的函数

export const getUserDetails = (email) => { 
    return (dispatch) => { 
     return axios.put('http://localhost:3030/user', user) .then((data) => { 
      // this is where the action is fired 
      dispatch({ 
       type: UPDATE_USER_DETAILS, 
       user:data.data 
      }); 

      // if you want to access the result of this API call, you can return here 
      // the returned promise will resolve to whatever you return here 

      return data; 
     }); 
    } 
}); 

当你绑定的动作的创造者,它会“解包”的创造者,同时保持方法签名 - 你通常会像你一样使用它

this.props.getUserDetails("[email protected]").then((data) => { 
    // optional resolved promise 
}) 
+0

我使用了redux-thunk,但我仍然得到相同的错误。 我是否需要在Actions中调度函数?即时通讯使用bindActionCreators。 – TRomesh

+0

但是,您需要从操作中返回一个“thunk”。我会更新我的评论。 –

+0

我刚刚注意到你正在尝试从一个承诺,没有实际返回承诺... –

相关问题