我在react-native中使用redux来从api获取数据,这是我到目前为止所做的事情
api_type.js
export const USER_LOGIN = 'user_login_action';
export const USER_LOGINING = 'logining_users';
export const USER_LOGEDIN = 'user_logged_in';
index.js
import axios from 'axios';
import { USER_LOGIN, USER_WALLETS,USER_LOGINING } from './api_types';
const AUTH_API_URL = 'http:/api/v1';
const CORE_API_URL = 'http:/api/v1';
let username="";
let password="";
let auth_token ="";
let AuthStr = "";
export function UserWallets(){
return function(dispatch){
AuthStr ="Bearer "+auth_token;
console.log ("new auth : "+AuthStr);
axios.defaults.headers.common['Authorization'] = AuthStr
axios.get(`${CORE_API_URL}/wallet/allwallets`)
.then(response => {
dispatch({
type: USER_WALLETS,
payload: response['data']
});
}).catch((error) => {
console.log(error);
})
}
}
export function UserLogin() {
return function(dispatch) {
dispatch({
type:USER_LOGINING
});
axios.post(
`${AUTH_API_URL}/authenticate/users`,
{
email: username,
password: password
}
)
.then(response => {
dispatch({
type: USER_LOGIN,
payload: response['data']
});
auth_token=response['data']['token'];
}
)
.catch((error) => {
console.log(error);
})
}
}
export function username(term) {
username=term;
console.log("username " +username);
return{
type:"username",
username
};
}
export function password(term) {
password=term;
console.log("password " +password);
return{
type:"password",
password
};
}
export function authToken (term){
auth_token = term;
return{
type:"authtoken",
auth_token
}
}
auth_reducer.js
import { USER_LOGIN ,USER_LOGINING } from '../actions/api_types';
const INTIAL_STATE = {
message: '',
token:'',
logging: false,
loggedin: false,
loginerr: null,
};
export default function (state = INTIAL_STATE, action) {
console.log("present state"+action.type);
switch(action.type) {
case USER_LOGIN:{
return { ...state, message: action.payload.message, token:action.payload.token,loggedin:true};
}
case USER_LOGINING:{
return {...state,logging:true }
}
default:{
console.log("default "+action.type);
}
}
return state;
}
index.js //合并reducer
import { combineReducers } from 'redux';
import drawer from './drawer';
import AuthReducer from './auth_reducer';
import CoreReducer from './core_reducer';
export default combineReducers({
auth: AuthReducer,
});
我已经创建并配置了商店,并将我的应用程序与react-redux的提供商一起包装,并且我已将商店传递给提供商,简而言之,我现在可以从我的组件访问商店。 下面是我的login_component中的一个函数,一旦我点击登录
就会触发login(){
if(this.state.email==""){
alert("Email require");
return;
}else if(this.state.password==""){
alert("password require");
return;
}else{
//set the paramter for the reducer to use
this.props.username(this.state.email);
this.props.password(this.state.password);
//activate the user login action
this.props.UserLogin();
if(!this.props.auth.loggedin){
console.log("logging in");
//show loadging gif
}
//checking from response from the auth api
if(this.props.auth.message=="user successfully logged in"){
alert(this.props.auth.token);
Actions.home();
}else{
alert("invalid Username/Password");
}
}
}
现在这是问题,一旦我点击登录,我评论的代码块(检查来自api的响应)将不会等待商店值在执行它之前改变,请我解决这个问题。< / p>
答案 0 :(得分:1)
我终于得到了问题的解决方案,api调用是异步但问题是在组件中,我在商店更改之前测试了响应所以这里是解决方案,我将以下内容添加到我的登录组件< / p>
componentWillReceiveProps(nextProps) {
console.log("component update");
if(nextProps.auth.loggedin==true){
if(nextProps.auth.message=="user successfully logged in"){
this.setState(previousState => {
return { spinnerv: false };
});
Actions.home();
}else{
alert("invalid Username/Password");
}
}
}
这里发生的是函数componentWillReceiveProps,检查状态是否已更改,然后如果响应是componentWillReceiveProps则发出文本。 感谢jmargolisvt的支持。 我希望这有助于其他人。
答案 1 :(得分:0)
您需要异步执行此API调用。基本上,您将使用您的登录功能调度异步操作以进行API调用。然后,根据API调用的成功/失败方法,您将调度另一个(同步)调用,该调用可以是否记录用户。
您希望合并Redux Thunks以进行异步通话。 https://github.com/gaearon/redux-thunk