In the last post (here: https://dev.to/skd1993/creating-a-simple-login-function-with-redux-and-thunk-in-react-native-33ib) I discussed the steps to create a simple login logic using Redux and Thunk in React Native.
Continuing from there, in this post, we will look at how can the login state be saved locally in the app. The same logic can be extended to other functions as well (and not just limited to login).
Why save locally?
You may not want you app's user to login everytime on launching the app. That would be cumbersome. There should be some mechanism to "remember" their situation (logged in : true or false).
Depending on what the status is you can choose to show some app screens (like profile page, content page) and skip others (like login page, sign up page).
What about Redux?
Redux can only maintain the state till the app in "on". If the user exits the app, or say for example, reboots the phone or the app crashes the state resets.
How can we do it?
Simply by maintaining a copy of your redux state locally on the device. We can AsyncStorage
library to achieve this. It will allow us to store JSON object in local storage.
Let's have a look at the steps now.
Install the AsyncStorage
library
Go in your project directory (where your package.json
exists) and:
- For npm users run
npm i @react-native-community/async-storage
- For yarn users run
yarn add @react-native-community/async-storage
Post installation, if you use React Native version <= 0.59 the you also need to link it by running: react-native link @react-native-community/async-storage
Reminder on Redux...
As discussed in the previous post, for sake of simplicity, all redux code is placed in a 'redux' folder, while the components are in 'src/components/< ComponentName >/index.js'.
This is how our redux folder looks like.
redux
├── actions.js
├── actionTypes.js
├── initialState.js
├── reducer.js
└── store.js
We currently have the following login
function to call the login API, and get back the data (in actions.js
)
import { Alert } from 'react-native'; // to show alerts in app
export const login = (loginInput) => {
const { username, password } = loginInput;
return (dispatch) => { // don't forget to use dispatch here!
return fetch(LoginUrl, {
method: 'POST',
headers: { // these could be different for your API call
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(loginInput),
})
.then((response) => response.json())
.then((json) => {
if (json.msg === 'success') { // response success checking logic could differ
dispatch(setLoginState({ ...json, userId: username })); // our action is called here
} else {
Alert.alert('Login Failed', 'Username or Password is incorrect');
}
})
.catch((err) => {
Alert.alert('Login Failed', 'Some error occured, please retry');
console.log(err);
});
};
};
To start using AsyncStorage
let's import it first:
import AsyncStorage from '@react-native-community/async-storage';
The let us tweak the response
part a bit to simplify:
if (json.msg === 'success') { // response success checking logic could differ
const o = { ...json, userId: username };
setLoginLocal(o); // storing in local storage for next launch
dispatch(setLoginState(o)); // our action is called here
}
As you can see, now setLoginLocal
function will take the data and be responsible for local storage. Same data is passed in the next line to our action dispatcher.
Let's create the setLoginLocal
function now in the same file.
const setLoginLocal = async (loginData) => {
try {
await AsyncStorage.setItem('loginData', JSON.stringify(loginData));
} catch (err) {
console.log(err);
}
};
NOTE: AsyncStorage can only store string data, so in order to store object data you need to serialize it first. For data that can be serialized to JSON you can use JSON.stringify()
when saving the data and JSON.parse()
when loading the data.
setItem()
is used both to add new data item (when no data for given key exists), and to modify exiting item (when previous data for given key exists).
And that's it! Simple and easy to understand. The login state object will now be stored locally on the device, and will persist even after app is closed / device reboots. It's just like an app-specific DB.
You can read more about the library here:
- https://www.npmjs.com/package/@react-native-community/async-storage
- https://react-native-community.github.io/async-storage/docs/install
In the coming posts, we will look at how to utilize this local state while loading the app on launch.
Hope this was helpful 😄
Top comments (0)