Adding redux
Part ɪɪ: React-Native UI│Story 09: Add redux and connect User Sign-in component to redux
GIT : Repo
| Feature/Story branch
| PR
If you are following the series, in this Part-II - React-Native UI, so far we’ve got the Google Sign-in and routing navigation implemented in our react-native app and added a couple of components for User Sign-in and Home screen.
Our next goal is to save the user details that we get from Google after user signs in, like user’s name, email and profile picture, in an application-wide state so that it’s available to other components of the app. To share data across components, we have few options available in react, like childProps or Context API (available officially in React 16+) or redux.
In our example, we would opt for redux, simply because I feel, for a large-scale application, redux is good option to maintain an application-wide state. It allows you to apply useful middlewares. GraphQL or MobX are also few other good options.
Lets get started:
Adding redux
With react-native app’s root folder as pwd on the terminal, run the command:
$ yarn add redux react-redux redux-logger
# or with npm
# npm install redux react-redux redux-logger --save
- 📂 Create a folder named
redux
undersrc
folder. - 📂 Under
redux
, create subfolders -actions
,reducers
andstore
Actions
Action Constants:
📄 Under actions
folder, add a file actionTypes.js
with below code: 👇
User Sign-In Actions:
- 📂 Create a folder
UserSignIn
undersrc/redux/actions
folder. - 📄 Add a file
UserSignInActions.js
undersrc/redux/actions/UserSignIn
folder 👇
Reducer for User Sign-in state:
Next, add a reducer to update the app state related to Google user’s basic profile data for the actions we defined above that would be triggered during the sign-in process. For sign in failure case, we would store failure reason in the store.
- 📄 Add file
UserSignInReducer.js
undersrc/redux/reducers
folder 👇
Under src\redux\reducers
, add index.js
, with below code:
Store:
Next, let’s create our redux store.
Under src\redux\store
, add index.js
with below code:
Wrapping App within redux Provider:
Update App.js
as below wrapping the root component with redux Provider providing it the store we created above:
Connect UserSignIn component to redux
Next, we will update our UserSignIn
component to connect to redux to update the User’s Sign-in status and Google user details in our store using the actions we defined in src/redux/actions/UserSignInActions.js
Under src/components/UserSignIn
, add a file UserSignInConnected.js
, with below code:
👆 above, we connected UserSignIn
component to redux. In the component, we are going to use redux dispatch actions that we created for the User Sign-in events to update the GoogleUser and GoogleSignIn store props. With this, we now have the redux dispatch actions, mapped in mapDispatchToProps
, available as props
in UserSignIn
component. So lets refactor UserSignIn
component as below:
Above, we did a quite a few changes to UserSignIn
component:
(line # 7–10)
component’s local state now has only two state variables -isSigninInProgress
andcheckingSignedInStatus
, we got rid ofloggedInUser
andisUserSignedIn
.loggedInUser
is not needed now because we would now store the logged in user in redux state variablegoogleUser
(this.props.googleUser)isUserSignedIn
state variable is also not needed now. We were using this state variable to render ‘Logout’ button instead of ‘Sign In’ button if its value is true. However, after we added navigation to our app, user would navigate to ‘Home’ screen and won’t stay on the same sign-in screen, thus ‘Logout’ button is not needed on this component. We would add Logout button later in ourAppHeader
component.(line # 29 - 33)
: react-navigation’sdidFocus
event subscription and removing the subscription on componentWillUnmount, its explained in the code comments(line # 22 - 28)
(line # 67 - 85)
: inonSignInPress
method, after user successfully signs in, we call a local methoddispatchOnSignIn (line # 90 - 98)
, that in turn callsthis.props.UserSignIn_onSuccess
( which is mapped to the dispatch actionUserSignIn_onSuccess
in the connected componentUserSignInConnnected
)(line # 103 - 110)
: also, if user is already signed in, we callgetCurrentUserInfo
function on line 114. In this function, we again calldispatchOnSignIn
after getting the currently signed in user’s details.(line # 129)
: in signOut, after signing out the user, we callthis.props.UserSignIn_logOut
which is mapped to dispatch actionUserSignIn_logOut
.(line # 180-182)
:InshowSignInError
method, before showing the sign-in error to user, we now also callthis.props.UserSignIn_onError
, which maps to the dispatch actionUserSignIn_onError
.
Now, instead of using UserSignIn
component as is, we would have to use the UserSignInConnected
component in the app. For this, lets update index.js
file under src/components
folder to export the component from UserSignInConnected
instead of UserSignIn 👇
Ok, the UserSignIn
component is now connected with redux actions and state. We are now dispatching the required actions from the component on events like successful sign-in, logout or sign-in error. Lets make sure the app is working good after all these changes. We haven’t made any changes to the functionality or UI, so we are expecting any change there, but because we added logger
as middleware to redux store, we are expecting the actions triggered to be logged to the chrome console. ( Make sure you have ‘react-native debugger’ opened in chrome. )
Now refresh the app on the simulator (it would have Hot reloaded if you have Hot reloading enabled on simulator’s developer menu ).
👆 note the UserSignIn_onSuccess
action getting triggered and logged in the background chrome’s debugger console. And on Android: 👇
(❗
️ it took me to restart the app on Android and chrome Remote Debugger couple of times for Remote debugging to work from Android).
Great! Now that we have the logged-in user’s details available in redux store, let’s build a header component next using this user data from redux to display user’s profile picture in the header along with a log out button.