0

当我提交我的登录表单时validateAndSignInUser,会调用这个signInUser发送到后端的电子邮件和密码以获取会话令牌。那行得通。signInUser发送返回值后signInUserSuccess,我验证了它的工作原理。但在那之后,UserReducer 没有被激活,我不明白为什么。怎么了?

我有这个动作SignInFormContainer.js

import { reduxForm } from 'redux-form';
import SignInForm from '../components/SignInForm';
import { signInUser, signInUserSuccess, signInUserFailure } from '../actions/UsersActions';

const validateAndSignInUser = (values, dispatch) => {
    return new Promise ((resolve, reject) => {
        let response = dispatch(signInUser(values));
        response.payload.then((payload) =>  {
            // if any one of these exist, then there is a field error 
            if(payload.status != 200) {
                // let other components know of error by updating the redux` state
                dispatch(signInUserFailure(payload));
                reject(payload.data); // this is for redux-form itself
            } else {
                // store JWT Token to browser session storage 
                // If you use localStorage instead of sessionStorage, then this w/ persisted across tabs and new windows.
                // sessionStorage = persisted only in current tab
                sessionStorage.setItem('dhfUserToken', payload.data.token);
                // let other components know that we got user and things are fine by updating the redux` state 
                dispatch(signInUserSuccess(payload)); 
                resolve(); // this is for redux-form itself
            }
        }).catch((payload) => {
            // let other components know of error by updating the redux` state
            sessionStorage.removeItem('dhfUserToken');
            dispatch(signInUserFailure(payload));
            reject(payload.data); // this is for redux-form itself
        });
    });
}

const mapDispatchToProps = (dispatch) => {
    return {
        signInUser: validateAndSignInUser /*,
        resetMe: () => {
            // sign up is not reused, so we dont need to resetUserFields
            // in our case, it will remove authenticated users
            // dispatch(resetUserFields());
        }*/
    }
}

function mapStateToProps(state, ownProps) {
    return { 
        user: state.user
    };
}

// connect: first argument is mapStateToProps, 2nd is mapDispatchToProps
// reduxForm: 1st is form config, 2nd is mapStateToProps, 3rd is mapDispatchToProps
export default reduxForm({
    form: 'SignInForm', 
    fields: ['email', 'password'], 
    null,
    null,
    validate 
}, mapStateToProps, mapDispatchToProps)(SignInForm);

这三个动作在UserActions.js

import axios from 'axios';

//sign in user
export const SIGNIN_USER = 'SIGNIN_USER';
export const SIGNIN_USER_SUCCESS = 'SIGNIN_USER_SUCCESS';
export const SIGNIN_USER_FAILURE = 'SIGNIN_USER_FAILURE';

export function signInUser(formValues) {
    const request = axios.post('/login', formValues);
    return {
        type: SIGNIN_USER,
        payload: request
    };
}

export function signInUserSuccess(user) {
    console.log('signInUserSuccess()');
    console.log(user);
    return {
        type: SIGNIN_USER_SUCCESS,
        payload: user
    }
}

export function signInUserFailure(error) {
    console.log('signInUserFailure()');
    console.log(error);
    return {
        type: SIGNIN_USER_FAILURE,
        payload: error
    }
}

这是我的减速机UserReducer.js

import {
    SIGNIN_USER, SIGNIN_USER_SUCCESS,  SIGNIN_USER_FAILURE,
} from '../actions/UsersActions';

const INITIAL_STATE = {user: null, status:null, error:null, loading: false};

export default function(state = INITIAL_STATE, action) {
  let error;    
  switch(action.type) {    
    case SIGNIN_USER:// sign in user,  set loading = true and status = signin
        return { ...state, user: null, status:'signin', error:null, loading: true}; 
    case SIGNIN_USER_SUCCESS://return authenticated user,  make loading = false and status = authenticated
        return { ...state, user: action.payload.data.user, status:'authenticated', error:null, loading: false}; //<-- authenticated
    case SIGNIN_USER_FAILURE:// return error and make loading = false
        error = action.payload.data || {message: action.payload.message};//2nd one is network or server down errors      
        return { ...state, user: null, status:'signin', error:error, loading: false};

    default:
        return state;
  }
}

减速机组合:

import { combineReducers } from 'redux';
import { UserReducer } from './UserReducer';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
    user: UserReducer,
    form: formReducer  // <-- redux-form
});

export default rootReducer;

configureStore.js

import {createStore, applyMiddleware, combineReducers, compose} from 'redux';
import thunkMiddleware from 'redux-thunk';
import {devTools, persistState} from 'redux-devtools';
import rootReducer from '../reducers/index';

let createStoreWithMiddleware;

// Configure the dev tools when in DEV mode
if (__DEV__) {
  createStoreWithMiddleware = compose(
    applyMiddleware(thunkMiddleware),
    devTools(),
    persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
  )(createStore);
} else {
  createStoreWithMiddleware = applyMiddleware(thunkMiddleware)(createStore);
}

export default function configureStore(initialState) {
  return createStoreWithMiddleware(rootReducer, initialState);
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import configureStore from './store/configureStore';
import {renderDevTools} from './utils/devTools';

const store = configureStore();

ReactDOM.render(
      <div>
        {/* <Home /> is your app entry point */}
        <Provider store={store}>
          <Router history={browserHistory} routes={routes} />
        </Provider>

        {/* only renders when running in DEV mode */
          renderDevTools(store)
        }
      </div>
    , document.getElementById('main'));
4

0 回答 0