2017-05-24 9 views
3

Ich bekomme einen Fehler wie Aktionen müssen einfache Objekte sein. Verwenden Sie benutzerdefinierte Middleware für asynchrone Aktionen während der Verwendung von Redox. Ich entwickle eine Anwendung mit einer Login-Funktionalität. Hier ist mein Code.Aktionen müssen einfache Objekte sein, während Redux verwendet wird

Komponente

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); 

Aktionen

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); 
     }); 
} 

Reducer

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 
}) 

Shop

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__()); 
} 

Der Browser zeigt den Fehler als enter image description here

Wie dieses Problem zu überwinden ?. Ich bin zu redux ziemlich neu.

Antwort

2

Vanilla redux Griffe nur einfache Objektaktionen wie

{ type: SOME_ACTION, ...parameters }

zurück synchron.

Sie müssen sich mit der Verwendung von Middleware wie redux-thunk befassen, wenn Sie Promises oder wirklich etwas anderes als ein einfaches Objekt von Ihren Aktions-Erstellern (oder in diesem Fall asynchronen Aktionen) zurückgeben möchten.

sehen: How to dispatch a Redux action with a timeout?

edit:

Das Problem ist eine Art zweifach:

zuerst:

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

Sie Rückkehr ein Aktion im Inneren des Pro mise (axios.put) aber du gibst das Versprechen nicht zurück - Javascript funktioniert nicht so, wie du es willst. return ist in diesem Fall auf den nächsten übergeordneten Bereich beschränkt; in diesem Fall der Versprechungskörper. Wenn Sie nur angeben, was Sie gerade haben, ist der Rückgabetyp des Aktionserstellers getUserDetailsundefined.

gibt eine Promise<Action> zurück, die Ihr Problem immer noch nicht wirklich löst.

Sekunde: Wenn mit redux-Thunk arbeiten, können Sie Ihre Aktion in einer Funktion wie

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; 
     }); 
    } 
}); 

wickeln, wenn Sie die Aktion Schöpfer binden, wird es „auspacken“ der Schöpfer, während die Signaturverfahren halten - Sie benutzen es wie Sie normalerweise

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

Ich benutzte redux-thunk, aber ich habe immer noch den gleichen Fehler. Muss ich die Funktionen in Aktionen versenden? Ich benutze bindActionCreators. – TRomesh

+0

Sie müssen jedoch einen "Thunk" von Ihren Aktionen zurückgeben. Ich werde meinen Kommentar aktualisieren. –

+0

und ich habe gerade festgestellt, dass Sie von innen ein Versprechen versuchen, ohne tatsächlich das Versprechen zurückzugeben ... –

Verwandte Themen