使用 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)
);
};
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)
);
我正在尝试使用 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)
);
};
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)
);