Вы можете удобно использовать только AsyncStorage ИЛИ Redux для управления состоянием аутентификации.Зависит от того, с чем вам удобно.Я приведу пример обоих.
Для AsyncStorage: при условии, что у вас есть ключи аутентификации, действительные только в течение 2 недель.Вы можете принять к сведению, когда ваш пользователь входит в систему и сэкономить время.Например:
//LoginScreen
import { onSignIn } from '../actions/auth'; //I will describe the onSignInMethod below
import axios from 'axios'; //lets use axios. You may use fetch too.
export default class LoginScreen extends Component {
//your code: state, static etc
loginMethod = () => {
const url = yourauthUrl;
const payload = {
email: this.state.email,
password: this.state.password
};
axios.post(url, payload)
.then((response) => {
if (response.status == 200) {
const dateOfLastLogin = new Date().getTime().toString(); //take note of the time the user logs in.
AsyncStorage.setItem('dateOfLastLogin', dateOfLastLogin);
}
})
.then(() => {
onSignIn() //onSignIn handles your sign in. See below.
.then(() => this.props.navigation.navigate('AfterSignInPage'));
})
.catch(() => { // your callback if onSignIn Fails
});
})
.catch((error) => { //your callback if axios fails
});
}
}
В ../actions/auth.js
import { AsyncStorage } from 'react-native';
export const onSignIn = () => AsyncStorage.setItem('auth_key', 'true');
//in LoginScreen we called this to set that a user has successfully logged in
//why is true a string? -- Because Asyncstorage stores only strings
export const onSignOut = () => AsyncStorage.multiRemove(['auth_key', 'dateOfLastLogin']);
//now lets create a method that checks if the user is logged in anytime
export const isSignedIn = () => {
return new Promise((resolve, reject) => {
AsyncStorage.multiGet(['auth_key', 'dateOfLastLogin'])
.then((res) => {
const userKey = res[0][1];
const lastLoginDate = parseInt(res[1][1]);
const today = new Date().getTime();
const daysElapsed = Math.round(
(today - lastLoginDate) / 86400000
);
if (userKey !== null && (daysElapsed < 14)) {
resolve(true);
} else {
resolve(false);
}
})
.catch((err) => reject(err));
});
};
теперь мы можем import { isSignedIn } from '../actions/auth';
из любого из наших компонентов и использовать его следующим образом:
isSignedIn()
.then((res) => {
if (res) {
// user is properly logged in and the login keys are valid and less than 14 days
}
})
////////////////////////////////////////////////////////////////////////////
Если вы хотите использовать redux
Обработка логина в redux
В вашем types.js
//types.js
export const LOGGED_IN = 'LOGGED_IN';
В ваших действиях с избыточностью
//loginActions.js
import {
LOGGED_IN,
} from './types';
export function login() {
let dateOfLastLogin = null;
let isLoggedIn = 'false';
AsyncStorage.multiGet(['auth_key', 'dateOfLastLogin'])
.then((res) => {
isLoggedIn = res[0][1];
dateOfLastLogin = parseInt(res[1][1]);
}); //note this works asynchronously so, this may not be a good approach
return {
type: LOGGED_IN,
isLoggedIn,
dateOfLastLogin
};
}
В вашем логинеReducer
//LoginReducer.js
import {
LOGGED_IN
} from '../actions/types';
const initialState = {
userIsLoggedIn: false
};
export function loginReducer(state=initialState, action) {
switch (action.type) {
case LOGGED_IN:
const userKey = action.isLoggedIn;
const lastLoginDate = action.dateOfLastLogin;
const today = new Date().getTime();
const daysElapsed = Math.round(
(today - lastLoginDate) / 86400000
);
let trulyLoggedIn = false;
if (userKey !== null && (daysElapsed < 14)) {
trulyLoggedIn = true;
} else { trulyLoggedIn = false }
return {
userIsLoggedIn: trulyLoggedIn
};
default:
return state;
}
}
В вашем ./reducers/index.js
//reducers index.js
import { combineReducers } from 'redux';
import { loginReducer } from './LoginReducers';
const rootReducer = combineReducers({
loggedIn: loginReducer
});
export default rootReducer;
В вашем магазине, где вы использовали redux-thunk, примените MidWare.Давайте назовем его configureStore.js
//configureStore.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
applyMiddleware(thunk)
);
}
В вашем App.js
//App.js
import { Provider } from 'react-redux';
import configureStore from './src/store/configureStore'; //where you configured your store
import { YourMainNavigator } from '../src/config/router'; //where your root navigator is
const store = configureStore();
export default class App extends Component<{}> {
render() {
return (
<Provider store={store}>
<YourMainNavigator />
</Provider>
);
}
}
Вы должны знать, что вам больше не нужен метод isSignedIn в вашем auth.js
Ваш метод входа остается прежнимкак описано выше в LoginScreen.
Теперь вы можете использовать redux для проверки состояния входа в систему следующим образом:
import React, {Component} from 'react';
import {connect} from 'react-redux';
class MyComponent extends Component {
someFunction() {
if (this.props.loggedIn) {
//do something
}
}
}
const mapStateToProps = (state) => {
return {
loggedIn: state.loggedIn.userIsLoggedIn
};
}
export default connect(mapStateToProps)(MyComponent);
Должен быть лучший способ использования redux для управления входом - лучше, чемчто я изложил здесь.Я думаю, вы также можете использовать redux для управления состоянием входа в систему без использования AsyncStorage.Все, что вам нужно сделать, - это на вашем loginScreen, если функции входа возвращают response.status == 'ok', вы можете отправить действие для переадресации, в которое входит пользователь. В приведенном выше примере с использованием asyncstorage вам может потребоваться толькоиспользуйте избыточность, чтобы проверить, вошел ли пользователь в систему.