使用 React 和 Redux 登录 api 请求

login api request using react and redux

我正在尝试使用 react & redux 制作一个小项目。此项目的 Main 页面是 login。我已经有一个可用的 api 用于登录。以下是我项目中的代码片段:

login.js

onLoginFormSubmit(event) {
    event.preventDefault();
    this.props.actions.login(this.state.username, this.state.password);
  }

render() {
    return (
      ...Login Form ...
    );
  }
}

Login.propTypes = {
  actions: PropTypes.object.isRequired,

};

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

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(loginAction, dispatch)
  }
}

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

loginReducer.js

import {
  LOGIN_SUCCESS,
  LOGIN_FAILED,
  LOGIN_ATTEMPT
} from '../actions/type';
import Immutable from 'immutable';

const initialState = new Immutable.Map({
  username: '',
  password: '',
  isLoggingIn: false,
  isLoggedIn: false,
  error: null
});

export default function user(state = initialState, action){
  switch (action.type){
    case LOGIN_ATTEMPT:
      console.log("LOGIN_ATTEMPT: ",action.user);
      return state.merge({
        isLoggingIn: true,
        isLoggedIn: false,
        username: action.user.username,
        password: action.user.password
      });

    case LOGIN_FAILED:
      console.log("LOGIN_FAILED: ");
      return state.merge({
        error: action.error,
        isLoggingIn: false,
        isLoggedIn: false
      });

    case LOGIN_SUCCESS:
      console.log("LOGIN_SUCCESS: ",action);
      return state.merge({
        error: null,
        isLoggingIn: false,
        isLoggedIn: true
      })
      break;

    default:
      return state;

  }
}

loginAction.js

export function loginError(error){
  return  { error, type: LOGIN_FAILED };
}

export function loginSuccess(response){
  return dispatch => {
    dispatch({ response, type: LOGIN_SUCCESS});
  };
}

export function loginRequest(username, password){
  const user = {username: username, password: password};
  return { user, type: LOGIN_ATTEMPT };
}


export function login(username, password) {
  console.log("User Data: ", username, password);
    return dispatch =>
    fetch('http://192.168.1.100:9090/login', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        username: username,
        password: password
      }),
    })
    .then(response => {
      console.log("I'm here");
      if(response.status >= 200 && response.status < 300){
        console.log("Response; ", response);
        dispatch(loginSuccess(response));
      } else {
        const error = new Error(response.statusText);
        error.response = response;
        dispatch(loginError());
        throw error;
      }
    })
    .catch(error => { console.log('Request Failed: ', error);});
  }

问题是,login api 没有被调用。我在控制台中遇到的唯一错误是 Uncaught Error: Actions must be plain objects。使用自定义中间件进行异步操作。

我知道有 redux-thunk 用于异步调用,但不知道如何使用它。我还在学习。因此,我们将不胜感激。

谢谢。

要使异步操作起作用,您可以使用 redux-thunk。使用它非常简单。只需在创建商店时将其加载到中间件即可。

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

export default (initialState = {}) => {

  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk)
  );

};

DOCS:

npm install --save redux-thunk

然后,要启用 Redux Thunk,请使用 applyMiddleware():

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

// Note: this API requires redux@>=3.1.0
const store = createStore(
  rootReducer,
  applyMiddleware(thunk)
);