SlideShare a Scribd company logo
1 of 46
Download to read offline
Beginner’s
Tutorial (Part-2):
How to
Integrate
Redux-Saga in
React Native
App
www.bacancytechnology.com
We have learned and implemented the
basics of redux-form in our previous
tutorial: Integrate Redux Form (Part-1). You
can visit the tutorial if you don’t have a
basic idea of Redux Form or are struggling
to use it in your application. Now, it’s time
to step up and introduce redux-saga with
redux form. Are you looking for a simple
tutorial to get started with redux
middleware in your react native
application? If yes, then you have chosen
the correct blog!
In this tutorial, we will implement an
authentication module in our demo
application using redux-saga and redux
form.
Goal: Simple
Redux-Form &
React-Saga
Example
Before moving towards implementing our
authentication module, watch the video
below to have a better idea of the demo
application.
Tutorial
Takeaway
Redux-Saga
Redux-Form
Register
Login
Dashboard
Field Array – Field Array component is
used for rendering an array of fields.
Wizard Form – The common pattern for
separating a single form into different
input pages is Wizard.
Mainly we will learn about-
The demo will contain an Authentication
module in which we have used redux-form.
The module will have-
Use of two redux-form features:
And also called Firebase REST API from the
Login and Register module.
So, we are clear with the requirements and
what the demo will contain. Without
wasting more time, let’s get started with
building our demo application.
Redux Store
Set up
The very first step will be setting up the
store.
For connecting the store to your
application, open app/index.js
app/index.js
import { store } from 'store'
import { Provider as ReduxProvider } from
'react-redux'
export default () => (
<ReduxProvider store={store}>
<App/>
</ReduxProvider>
)
Individual action.js and saga.js file for the
Register and Login Page (which we will see
in the coming sections)
A folder named store having three files –
index.js, reducers.js, and sagas.js
So, now the store is accessible through our
entire application. It’s time to use the store in
our app. For that, we will need to do two things-
store/index. js
import createSagaMiddleware from 'redux-
saga';
import {createStore, applyMiddleware}
from 'redux';
import {combinedReducers} from
'./reducers';
import rootSaga from './sagas';
const sagaMiddleware =
createSagaMiddleware();
const middlewares = [sagaMiddleware];
const store =
createStore(combinedReducers,
applyMiddleware(...middlewares));
sagaMiddleware.run(rootSaga);
export {store};
store/reducers.js
import {combineReducers} from 'redux';
import {reducer as formReducer} from
'redux-form';
export const combinedReducers =
combineReducers({
form: formReducer,
Auth: AuthReducer,
});
store/sagas.js
import {all} from 'redux-saga/effects';
import loginScreenSaga from
'screens/Login/saga';
import signupScreenSaga from
'screens/Register/saga';
function* rootSaga() {
yield all([loginScreenSaga(),
signupScreenSaga()]);
}
export default rootSaga;
Register
RegisterPageOne.js
RegisterPageTwo.js
RegisterPageThree.js
We will separate the Register form into
separate pages of inputs named-
This pattern of splitting is known as Wizard
Form.
Register/index.js
To separate the form into small forms we
will use a state variable- page for keeping
track of the page to be rendered.
import React, { useState } from 'react’
import { ScrollView } from 'react-native'
import RegisterPageOne from
'./RegisterPageOne'
import RegisterPageTwo from
'./RegisterPageTwo'
import RegisterPageThree from
'./RegisterPageThree'
const Register = (props) => {
const [page,setPage] = useState(1)
const onSubmit = (Values) => console.log(Values)
const goToNextPage = () => setPage( page =>
page + 1 )
const goToPrevPage = () => setPage( page =>
page - 1 )
return (
<ScrollView>
{page === 1 && <RegisterPageOne nextPage=
{goToNextPage} />}
{page === 2 && <RegisterPageTwo nextPage=
{goToNextPage} prevPage={goToPrevPage} />}
{page === 3 && <RegisterPageThree onSubmit=
{onSubmit} prevPage={goToPrevPage} />}
</ScrollView>
)
}
export default Register
Register/RegisterPageOne.js
RegisterPageOne is our first component
which will have two fields : Full Name and
User Name.
import React from 'react'
import { View } from 'react-native'
import { Field, reduxForm } from 'redux-
form'
import { FormInput , CustomButton } from
'components'
import { usernameRequired ,
fullnameRequired } from 'utils/Validations'
const RegisterPageOne =
({handleSubmit,nextPage}) => {
return (
<View>
<Field
name="fullName"
component={FormInput}
validate={[fullnameRequired]}
placeholder="Enter Full Name"
/>
<Field
name="userName"
component={FormInput}
validate={[usernameRequired]}
placeholder="Enter User Name"
onSubmitEditing = {handleSubmit(nextPage)}
/>
<CustomButton
buttonLabel="Next"
onPress={handleSubmit(nextPage)}
/>
</View>
)
}
export default reduxForm({
form: 'register-form',
destroyOnUnmount: false,
forceUnregisterOnUnmount: true
})(RegisterPageOne)
Register/RegisterPageTwo.js
RegisterPageTwo is our second component
having three fields: Mobile No, Email, and
Hobbies. The input for hobbies uses the
FieldArray API to render multiple inputs to
the user. We will also add validation to the
input fields.
import React from 'react'
import { StyleSheet, View , Text } from
'react-native'
import { Field, FieldArray, reduxForm } from
'redux-form'
import { DeleteButton, CustomButton,
FormInput } from 'components'
import { emailRequired, mobileNoRequired,
validateEmail, validateMobileno } from
'utils/Validations'
const renderHobbies = ({ fields, meta : {error
, submitFailed } }) => {
return(
<View>
<CustomButton
buttonLabel={“Add Hobby”}
onPress={() => fields.push({})}
/>
{fields.map((hobby,index) => (
<View key={index}>
<Field
name={hobby}
placeholder={`Hobby #${index + 1 }`}
component={FormInput}
/>
<DeleteButton onDelete={() =>
fields.remove(index)} />
</View>
))}
{ submitFailed && error && <Text>{error}
</Text> }
</View>
)
}
const validate = (values,props) => {
const errors = {}
if (!values.hobbies ||
!values.hobbies.length) errors.hobbies = {
_error : “Add at least One hobby” }
else{
const hobbiesArrayErrors = []
values.hobbies.forEach((hobby,index)=>{
if (!hobby || !hobby.length)
hobbiesArrayErrors[index] =
HOBBY_REQUIRED
})
if(hobbiesArrayErrors.length)
errors.hobbies = hobbiesArrayErrors
}
return errors
}
const RegisterPageTwo =
({prevPage,handleSubmit,nextPage}) => {
return (
<View>
<Field
name="mobileNo"
component={FormInput}
placeholder={“Enter Mobile Number”}
validate=
{[mobileNoRequired,validateMobileno]}
/>
<Field
name="email"
component={FormInput}
placeholder={“Enter email”}
validate={[emailRequired,validateEmail]}
/>
<FieldArray name="hobbies" component=
{renderHobbies}/>
<CustomButton buttonLabel={“Back”}
onPress={prevPage}/>
<CustomButton
buttonLabel={“Next”}
onPress={handleSubmit(nextPage)}
/>
</View>
)
}
export default reduxForm({
form: 'register-form',
validate,
destroyOnUnmount : false,
forceUnregisterOnUnmount : true
})(RegisterPageTwo)
import React from 'react'
import { View } from 'react-native'
import { connect } from 'react-redux'
import { Field, formValueSelector,
reduxForm } from 'redux-form'
import { CustomButton, FormInput } from
'components'
import { passwordRequired,
validatePassword } from 'utils/Validations'
let RegisterPageThree =
({handleSubmit,onSubmit,prevPage}) => {
const validateConfirmPassword =
(password) =>
Register/RegisterPageThree.js
The RegisterPageThree component includes
two password fields. Added validation that
both passwords should match.
password && password !==
props.password
? VALIDATE_CONFIRM_PASSWORD
: undefined
return (
<View>
<Field
name="password"
component={FormInput}
placeholder={“Enter Password”}
validate=
{[passwordRequired,validatePassword]}
/>
<Field
name="confirmPassword"
component={FormInput}
placeholder={“Re Enter Password”}
validate=
{[passwordRequired,validateConfirmPassw
ord]}
/>
<CustomButton buttonLabel={“Back”}
onPress={prevPage}/>
<CustomButton buttonLabel={“Next”}
onPress={handleSubmit(nextPage)}/>
</View>
)
}
RegisterPageThree = reduxForm({
form: 'register-form',
destroyOnUnmount : false,
forceUnregisterOnUnmount : true
})(RegisterPageThree)
const selector =
formValueSelector('register-form')
export default RegisterPageThree =
connect(state => {
const password = selector(state, 'password')
return {password}
})(RegisterPageThree)
Register/action.js
export const signupUser = user => ({
type: 'REGISTER_REQUEST',
payload: user,
});
Register/saga.js
import {put, takeLatest} from 'redux-
saga/effects';
import {userSignup} from 'api/Signup';
function* signupUser({payload}) {
try {
const response = yield
userSignup(payload);
yield put({type: 'REGISTER_SUCCESS',
response});
} catch (error) {
yield put({type: 'REGISTER_FAILURE',
error: error.message});
}
}
export default function*
signupScreenSaga() {
yield takeLatest('REGISTER_REQUEST',
signupUser);
}
Explanation
On clicking submit button, onSubmit
will be called, and signupUser(payload)
will be dispatched containing payload.
dispatch(signupUser(payload))
From the file Register/action.js, the
Register action type
“REGISTER_REQUEST” will be
dispatched.
Then saga middleware will watch for
the “REGISTER_REQUEST” type action.
It will take the latest encounter of that
action and call the register API.
For a successful call, it will dispatch the
“REGISTER_SUCCESS” action with
response data.
For a Fail call, it will dispatch the
“REGISTER_FAILURE” action with an
error message.
Update
Reducer
Open store/reducers.js and add this chunk
of code stating switch cases
This reducer serves actions coming from
Login and Register. Both the modules
dispatch similar types of actions-
1. Request Action: Upon this action, the
reducer updates the loading variable to
true.
2. Success Action: Upon this action, the
reducer updates the loading variable to
false and stores the response from the
action to the uservariable.
3. Failure Action: Upon this action, the
reducer updates the loading variable to
false and stores response coming from
action to error variable
const AuthReducer = (state = initialState,
action) => {
switch (action.type) {
case 'REGISTER_REQUEST':
return {
...state,
loading: true,
};
case 'REGISTER_SUCCESS':
return {
...state,
user: action.response,
loading: false,
};
case 'REGISTER_FAILURE':
return {
...state,
error: action.error,
loading: false,
};
store/reducers.js
case 'LOGIN_REQUEST':
return {
...state,
loading: true,
};
case 'LOGIN_SUCCESS':
return {
...state,
user: action.response,
loading: false,
};
case 'LOGIN_FAILURE':
return {
...state,
error: action.error,
loading: false,
};
default:
return state;
}
};
Log In
The Login page accepts two inputs- email
and password.
Login API is called on clicking onSubmit
Button. After successful login Dashboard
screen will appear.
Login/index.js
import React from 'react'
import { Field, reduxForm } from 'redux-
form'
import { useDispatch } from 'react-redux'
import { View, ScrollView } from 'react-
native'
import { loginUser } from './actions'
import { FormInput, CustomButton } from
'components'
import { passwordRequired, emailRequired,
validatePassword , validateEmail } from
'utils/Validations'
const Login = (props) => {
const dispatch = useDispatch()
const onSubmit = (values) =>
dispatch(loginUser(values))
return (
<ScrollView>
<Field
name="email"
component={FormInput}
placeholder={“Enter Email”}
validate={[emailRequired,validateEmail]}
/>
<Field
name="password"
component={FormInput}
placeholder={“Enter Password”}
validate={[passwordRequired,validatePassword]}
/>
<CustomButton
buttonLabel={“Login”}
onPress={props.handleSubmit(onSubmit)}
/>
</ScrollView>
)
}
export default reduxForm({
form: 'login-form'
})(Login)
Login/action.js
export const loginUser = (user) => ({
type: "LOGIN_REQUEST",
payload: user,
});
Login/saga.js
import {put, takeLatest} from 'redux-
saga/effects';
import {userLogin} from 'api/login';
function* loginUser({payload}) {
try {
const response = yield userLogin(payload);
yield put({type: 'LOGIN_SUCCESS',
response});
} catch (error) {
yield put({type: 'LOGIN_FAILURE', error:
error.message});
}
}
export default function* loginScreenSaga() {
yield takeLatest('LOGIN_REQUEST',
loginUser);
}
Explanation
On clicking the submit button, onSubmit
will be called, and loginUser(values) will
be dispatched containing the user email
and password.
const onSubmit = (values) =&gt;
dispatch(loginUser(values))
From the file Login/action.js, the Login
action type “LOGIN_REQUEST” will be
dispatched.
Then saga middleware will watch for
the “LOGIN_REQUEST” type action.
It will take the latest encounter of that
action and call the login API.
For a successful call, it will dispatch the
“LOGIN_SUCCESS” action with
response data.
For a Fail call, it will dispatch the
“LOGIN_FAILURE” action with an error
message.
API Call
const API_KEY = '' //put your key here
const endpoint = {
login :
`https://identitytoolkit.googleapis.com/v1/accou
nts:signInWithPassword?key=${API_KEY}`
}
export const userLogin = async (user) => {
const response = await fetch(endpoint.login,{
method: 'POST',
headers: {
'Content-Type' : 'application/json'
},
body: JSON.stringify({
email: user.email,
password: user.password,
returnSecureToken: true
})
})
if(!response.ok) throw new Error('Something
Went Wrong!!');
const responseData = await response.json()
return responseData.email
}
api/login/index.js
Dashboard
import React from 'react';
import {useSelector} from 'react-redux';
import {scale, verticalScale} from 'react-
native-size-matters';
import {Text, StyleSheet, SafeAreaView}
from 'react-native';
import Colors from 'utils/Colors';
const DashBoard = () => {
const userEmail = useSelector(state =>
state.Auth.user);
return (
<SafeAreaView style={styles.screen}>
<Text style={styles.hiText}>Hii,
there</Text>
Once you are successfully logged in, you’ll
be redirected to the dashboard page. Here’s
the code for the UI.
Dashboard/index.js
<Text style={styles.name}>{userEmail}
</Text>
</SafeAreaView>
);
};
export default DashBoard;
useSelector() allows you to extract data
from the Redux store state, using a selector
function, so that we can use it in our
component. As you can see, we can get the
value of the user’s email address from
state.Login.user.
You can find the entire source code of the
demo application at Github Repository,
from where you can clone and play around
with code.
Conclusion
So, this was about implementing redux-saga
with your redux-form in React Native
application. We have covered complete
authentication using redux-form features
Field Array, Wizard Form, and redux-
middleware. You can visit the React Native
Tutorials page for more such tutorials and
clone the github repository to experiment.
If you are looking for a helping hand for
your React Native application, please
contact us today to hire React Native
developers from us. We have experienced
and skilled developers having fundamental
and advanced knowledge of React Native.
Thank You
www.bacancytechnology.com

More Related Content

What's hot

Cis 407 i lab 6 of 7
Cis 407 i lab 6 of 7Cis 407 i lab 6 of 7
Cis 407 i lab 6 of 7
helpido9
 
Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
martinlippert
 
e computer notes - Creating views
e computer notes - Creating viewse computer notes - Creating views
e computer notes - Creating views
ecomputernotes
 
Getting started-with-oracle-so a-9
Getting started-with-oracle-so a-9Getting started-with-oracle-so a-9
Getting started-with-oracle-so a-9
Amit Sharma
 
02 asp.net session02
02 asp.net session0202 asp.net session02
02 asp.net session02
Mani Chaubey
 
Cis407 a ilab 6 web application development devry university
Cis407 a ilab 6 web application development devry universityCis407 a ilab 6 web application development devry university
Cis407 a ilab 6 web application development devry university
lhkslkdh89009
 
Angularjs Live Project
Angularjs Live ProjectAngularjs Live Project
Angularjs Live Project
Mohd Manzoor Ahmed
 
Cis 407 i lab 5 of 7
Cis 407 i lab 5 of 7Cis 407 i lab 5 of 7
Cis 407 i lab 5 of 7
helpido9
 

What's hot (20)

Best Practices for Magento Debugging
Best Practices for Magento Debugging Best Practices for Magento Debugging
Best Practices for Magento Debugging
 
A comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter componentA comprehensive guide on developing responsive and common react filter component
A comprehensive guide on developing responsive and common react filter component
 
Cis 407 i lab 6 of 7
Cis 407 i lab 6 of 7Cis 407 i lab 6 of 7
Cis 407 i lab 6 of 7
 
Why SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScriptWhy SOLID matters - even for JavaScript
Why SOLID matters - even for JavaScript
 
e computer notes - Creating views
e computer notes - Creating viewse computer notes - Creating views
e computer notes - Creating views
 
Wheels
WheelsWheels
Wheels
 
Build your first rpa bot using IBM RPA automation
Build your first rpa bot using IBM RPA automationBuild your first rpa bot using IBM RPA automation
Build your first rpa bot using IBM RPA automation
 
Getting started-with-oracle-so a-9
Getting started-with-oracle-so a-9Getting started-with-oracle-so a-9
Getting started-with-oracle-so a-9
 
МИХАЙЛО БОДНАРЧУК «SuperCharged End to End Testing with CodeceptJS» QADay 2019
МИХАЙЛО БОДНАРЧУК «SuperCharged End to End Testing with CodeceptJS»  QADay 2019МИХАЙЛО БОДНАРЧУК «SuperCharged End to End Testing with CodeceptJS»  QADay 2019
МИХАЙЛО БОДНАРЧУК «SuperCharged End to End Testing with CodeceptJS» QADay 2019
 
Vendor Attribute Addon - Magento2 Multi-Vendor Marketplace By CedCommerce
Vendor Attribute Addon - Magento2 Multi-Vendor Marketplace By CedCommerceVendor Attribute Addon - Magento2 Multi-Vendor Marketplace By CedCommerce
Vendor Attribute Addon - Magento2 Multi-Vendor Marketplace By CedCommerce
 
Dojo1.0_Tutorials
Dojo1.0_TutorialsDojo1.0_Tutorials
Dojo1.0_Tutorials
 
How to dynamically add remove input fields in php with jquery ajax
How to dynamically add  remove input fields in php with jquery ajaxHow to dynamically add  remove input fields in php with jquery ajax
How to dynamically add remove input fields in php with jquery ajax
 
Xsd files
Xsd files Xsd files
Xsd files
 
02 asp.net session02
02 asp.net session0202 asp.net session02
02 asp.net session02
 
Cis407 a ilab 6 web application development devry university
Cis407 a ilab 6 web application development devry universityCis407 a ilab 6 web application development devry university
Cis407 a ilab 6 web application development devry university
 
Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0Neuerungen in JavaServer Faces 2.0
Neuerungen in JavaServer Faces 2.0
 
Beyond MVC
Beyond MVCBeyond MVC
Beyond MVC
 
Angularjs Live Project
Angularjs Live ProjectAngularjs Live Project
Angularjs Live Project
 
Handling action bar in Android
Handling action bar in AndroidHandling action bar in Android
Handling action bar in Android
 
Cis 407 i lab 5 of 7
Cis 407 i lab 5 of 7Cis 407 i lab 5 of 7
Cis 407 i lab 5 of 7
 

Similar to Beginner’s tutorial (part 2) how to integrate redux-saga in react native app

Similar to Beginner’s tutorial (part 2) how to integrate redux-saga in react native app (20)

Beginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native applicationBeginner’s tutorial (part 1) integrate redux form in react native application
Beginner’s tutorial (part 1) integrate redux form in react native application
 
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
EWD 3 Training Course Part 41: Building a React.js application with QEWD, Part 5
 
Battle of React State Managers in frontend applications
Battle of React State Managers in frontend applicationsBattle of React State Managers in frontend applications
Battle of React State Managers in frontend applications
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
 
React lecture
React lectureReact lecture
React lecture
 
React & Redux for noobs
React & Redux for noobsReact & Redux for noobs
React & Redux for noobs
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
 
MeetJS Summit 2016: React.js enlightenment
MeetJS Summit 2016: React.js enlightenmentMeetJS Summit 2016: React.js enlightenment
MeetJS Summit 2016: React.js enlightenment
 
Introduction to React for Frontend Developers
Introduction to React for Frontend DevelopersIntroduction to React for Frontend Developers
Introduction to React for Frontend Developers
 
Ways to Set Focus on an Input Field After Rendering in React.pptx
Ways to Set Focus on an Input Field After Rendering in React.pptxWays to Set Focus on an Input Field After Rendering in React.pptx
Ways to Set Focus on an Input Field After Rendering in React.pptx
 
Introducing Vuex in your project
Introducing Vuex in your projectIntroducing Vuex in your project
Introducing Vuex in your project
 
State manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to VuexState manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to Vuex
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
Introduction to React and MobX
Introduction to React and MobXIntroduction to React and MobX
Introduction to React and MobX
 
Academy PRO: React native - building first scenes
Academy PRO: React native - building first scenesAcademy PRO: React native - building first scenes
Academy PRO: React native - building first scenes
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
The evolution of redux action creators
The evolution of redux action creatorsThe evolution of redux action creators
The evolution of redux action creators
 
React outbox
React outboxReact outbox
React outbox
 
How to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScriptHow to Build ToDo App with Vue 3 + TypeScript
How to Build ToDo App with Vue 3 + TypeScript
 

More from Katy Slemon

More from Katy Slemon (20)

React Alternatives Frameworks- Lightweight Javascript Libraries.pdf
React Alternatives Frameworks- Lightweight Javascript Libraries.pdfReact Alternatives Frameworks- Lightweight Javascript Libraries.pdf
React Alternatives Frameworks- Lightweight Javascript Libraries.pdf
 
Data Science Use Cases in Retail & Healthcare Industries.pdf
Data Science Use Cases in Retail & Healthcare Industries.pdfData Science Use Cases in Retail & Healthcare Industries.pdf
Data Science Use Cases in Retail & Healthcare Industries.pdf
 
How Much Does It Cost To Hire Golang Developer.pdf
How Much Does It Cost To Hire Golang Developer.pdfHow Much Does It Cost To Hire Golang Developer.pdf
How Much Does It Cost To Hire Golang Developer.pdf
 
What’s New in Flutter 3.pdf
What’s New in Flutter 3.pdfWhat’s New in Flutter 3.pdf
What’s New in Flutter 3.pdf
 
Why Use Ruby On Rails.pdf
Why Use Ruby On Rails.pdfWhy Use Ruby On Rails.pdf
Why Use Ruby On Rails.pdf
 
How Much Does It Cost To Hire Full Stack Developer In 2022.pdf
How Much Does It Cost To Hire Full Stack Developer In 2022.pdfHow Much Does It Cost To Hire Full Stack Developer In 2022.pdf
How Much Does It Cost To Hire Full Stack Developer In 2022.pdf
 
How to Implement Middleware Pipeline in VueJS.pdf
How to Implement Middleware Pipeline in VueJS.pdfHow to Implement Middleware Pipeline in VueJS.pdf
How to Implement Middleware Pipeline in VueJS.pdf
 
How to Build Laravel Package Using Composer.pdf
How to Build Laravel Package Using Composer.pdfHow to Build Laravel Package Using Composer.pdf
How to Build Laravel Package Using Composer.pdf
 
Sure Shot Ways To Improve And Scale Your Node js Performance.pdf
Sure Shot Ways To Improve And Scale Your Node js Performance.pdfSure Shot Ways To Improve And Scale Your Node js Performance.pdf
Sure Shot Ways To Improve And Scale Your Node js Performance.pdf
 
How to Develop Slack Bot Using Golang.pdf
How to Develop Slack Bot Using Golang.pdfHow to Develop Slack Bot Using Golang.pdf
How to Develop Slack Bot Using Golang.pdf
 
IoT Based Battery Management System in Electric Vehicles.pdf
IoT Based Battery Management System in Electric Vehicles.pdfIoT Based Battery Management System in Electric Vehicles.pdf
IoT Based Battery Management System in Electric Vehicles.pdf
 
Understanding Flexbox Layout in React Native.pdf
Understanding Flexbox Layout in React Native.pdfUnderstanding Flexbox Layout in React Native.pdf
Understanding Flexbox Layout in React Native.pdf
 
The Ultimate Guide to Laravel Performance Optimization in 2022.pdf
The Ultimate Guide to Laravel Performance Optimization in 2022.pdfThe Ultimate Guide to Laravel Performance Optimization in 2022.pdf
The Ultimate Guide to Laravel Performance Optimization in 2022.pdf
 
New Features in iOS 15 and Swift 5.5.pdf
New Features in iOS 15 and Swift 5.5.pdfNew Features in iOS 15 and Swift 5.5.pdf
New Features in iOS 15 and Swift 5.5.pdf
 
How to Hire & Manage Dedicated Team For Your Next Product Development.pdf
How to Hire & Manage Dedicated Team For Your Next Product Development.pdfHow to Hire & Manage Dedicated Team For Your Next Product Development.pdf
How to Hire & Manage Dedicated Team For Your Next Product Development.pdf
 
Choose the Right Battery Management System for Lithium Ion Batteries.pdf
Choose the Right Battery Management System for Lithium Ion Batteries.pdfChoose the Right Battery Management System for Lithium Ion Batteries.pdf
Choose the Right Battery Management System for Lithium Ion Batteries.pdf
 
Flutter Performance Tuning Best Practices From the Pros.pdf
Flutter Performance Tuning Best Practices From the Pros.pdfFlutter Performance Tuning Best Practices From the Pros.pdf
Flutter Performance Tuning Best Practices From the Pros.pdf
 
Angular Universal How to Build Angular SEO Friendly App.pdf
Angular Universal How to Build Angular SEO Friendly App.pdfAngular Universal How to Build Angular SEO Friendly App.pdf
Angular Universal How to Build Angular SEO Friendly App.pdf
 
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdfHow to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
How to Set Up and Send Mails Using SendGrid in NodeJs App.pdf
 
Ruby On Rails Performance Tuning Guide.pdf
Ruby On Rails Performance Tuning Guide.pdfRuby On Rails Performance Tuning Guide.pdf
Ruby On Rails Performance Tuning Guide.pdf
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Recently uploaded (20)

Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 

Beginner’s tutorial (part 2) how to integrate redux-saga in react native app

  • 1. Beginner’s Tutorial (Part-2): How to Integrate Redux-Saga in React Native App www.bacancytechnology.com
  • 2. We have learned and implemented the basics of redux-form in our previous tutorial: Integrate Redux Form (Part-1). You can visit the tutorial if you don’t have a basic idea of Redux Form or are struggling to use it in your application. Now, it’s time to step up and introduce redux-saga with redux form. Are you looking for a simple tutorial to get started with redux middleware in your react native application? If yes, then you have chosen the correct blog! In this tutorial, we will implement an authentication module in our demo application using redux-saga and redux form.
  • 4. Before moving towards implementing our authentication module, watch the video below to have a better idea of the demo application.
  • 6. Redux-Saga Redux-Form Register Login Dashboard Field Array – Field Array component is used for rendering an array of fields. Wizard Form – The common pattern for separating a single form into different input pages is Wizard. Mainly we will learn about- The demo will contain an Authentication module in which we have used redux-form. The module will have- Use of two redux-form features:
  • 7. And also called Firebase REST API from the Login and Register module. So, we are clear with the requirements and what the demo will contain. Without wasting more time, let’s get started with building our demo application.
  • 9. The very first step will be setting up the store. For connecting the store to your application, open app/index.js app/index.js import { store } from 'store' import { Provider as ReduxProvider } from 'react-redux' export default () => ( <ReduxProvider store={store}> <App/> </ReduxProvider> )
  • 10. Individual action.js and saga.js file for the Register and Login Page (which we will see in the coming sections) A folder named store having three files – index.js, reducers.js, and sagas.js So, now the store is accessible through our entire application. It’s time to use the store in our app. For that, we will need to do two things- store/index. js import createSagaMiddleware from 'redux- saga'; import {createStore, applyMiddleware} from 'redux'; import {combinedReducers} from './reducers'; import rootSaga from './sagas'; const sagaMiddleware = createSagaMiddleware(); const middlewares = [sagaMiddleware];
  • 11. const store = createStore(combinedReducers, applyMiddleware(...middlewares)); sagaMiddleware.run(rootSaga); export {store}; store/reducers.js import {combineReducers} from 'redux'; import {reducer as formReducer} from 'redux-form'; export const combinedReducers = combineReducers({ form: formReducer, Auth: AuthReducer, });
  • 12. store/sagas.js import {all} from 'redux-saga/effects'; import loginScreenSaga from 'screens/Login/saga'; import signupScreenSaga from 'screens/Register/saga'; function* rootSaga() { yield all([loginScreenSaga(), signupScreenSaga()]); } export default rootSaga;
  • 14. RegisterPageOne.js RegisterPageTwo.js RegisterPageThree.js We will separate the Register form into separate pages of inputs named- This pattern of splitting is known as Wizard Form. Register/index.js To separate the form into small forms we will use a state variable- page for keeping track of the page to be rendered. import React, { useState } from 'react’ import { ScrollView } from 'react-native' import RegisterPageOne from './RegisterPageOne' import RegisterPageTwo from './RegisterPageTwo'
  • 15. import RegisterPageThree from './RegisterPageThree' const Register = (props) => { const [page,setPage] = useState(1) const onSubmit = (Values) => console.log(Values) const goToNextPage = () => setPage( page => page + 1 ) const goToPrevPage = () => setPage( page => page - 1 ) return ( <ScrollView> {page === 1 && <RegisterPageOne nextPage= {goToNextPage} />} {page === 2 && <RegisterPageTwo nextPage= {goToNextPage} prevPage={goToPrevPage} />} {page === 3 && <RegisterPageThree onSubmit= {onSubmit} prevPage={goToPrevPage} />} </ScrollView> ) } export default Register
  • 16. Register/RegisterPageOne.js RegisterPageOne is our first component which will have two fields : Full Name and User Name. import React from 'react' import { View } from 'react-native' import { Field, reduxForm } from 'redux- form' import { FormInput , CustomButton } from 'components' import { usernameRequired , fullnameRequired } from 'utils/Validations' const RegisterPageOne = ({handleSubmit,nextPage}) => { return ( <View> <Field name="fullName" component={FormInput} validate={[fullnameRequired]}
  • 17. placeholder="Enter Full Name" /> <Field name="userName" component={FormInput} validate={[usernameRequired]} placeholder="Enter User Name" onSubmitEditing = {handleSubmit(nextPage)} /> <CustomButton buttonLabel="Next" onPress={handleSubmit(nextPage)} /> </View> ) } export default reduxForm({ form: 'register-form', destroyOnUnmount: false, forceUnregisterOnUnmount: true })(RegisterPageOne)
  • 18. Register/RegisterPageTwo.js RegisterPageTwo is our second component having three fields: Mobile No, Email, and Hobbies. The input for hobbies uses the FieldArray API to render multiple inputs to the user. We will also add validation to the input fields. import React from 'react' import { StyleSheet, View , Text } from 'react-native' import { Field, FieldArray, reduxForm } from 'redux-form' import { DeleteButton, CustomButton, FormInput } from 'components' import { emailRequired, mobileNoRequired, validateEmail, validateMobileno } from 'utils/Validations' const renderHobbies = ({ fields, meta : {error , submitFailed } }) => { return(
  • 19. <View> <CustomButton buttonLabel={“Add Hobby”} onPress={() => fields.push({})} /> {fields.map((hobby,index) => ( <View key={index}> <Field name={hobby} placeholder={`Hobby #${index + 1 }`} component={FormInput} /> <DeleteButton onDelete={() => fields.remove(index)} /> </View> ))} { submitFailed && error && <Text>{error} </Text> } </View> ) } const validate = (values,props) => {
  • 20. const errors = {} if (!values.hobbies || !values.hobbies.length) errors.hobbies = { _error : “Add at least One hobby” } else{ const hobbiesArrayErrors = [] values.hobbies.forEach((hobby,index)=>{ if (!hobby || !hobby.length) hobbiesArrayErrors[index] = HOBBY_REQUIRED }) if(hobbiesArrayErrors.length) errors.hobbies = hobbiesArrayErrors } return errors } const RegisterPageTwo = ({prevPage,handleSubmit,nextPage}) => { return (
  • 21. <View> <Field name="mobileNo" component={FormInput} placeholder={“Enter Mobile Number”} validate= {[mobileNoRequired,validateMobileno]} /> <Field name="email" component={FormInput} placeholder={“Enter email”} validate={[emailRequired,validateEmail]} /> <FieldArray name="hobbies" component= {renderHobbies}/> <CustomButton buttonLabel={“Back”} onPress={prevPage}/> <CustomButton buttonLabel={“Next”} onPress={handleSubmit(nextPage)} />
  • 22. </View> ) } export default reduxForm({ form: 'register-form', validate, destroyOnUnmount : false, forceUnregisterOnUnmount : true })(RegisterPageTwo)
  • 23. import React from 'react' import { View } from 'react-native' import { connect } from 'react-redux' import { Field, formValueSelector, reduxForm } from 'redux-form' import { CustomButton, FormInput } from 'components' import { passwordRequired, validatePassword } from 'utils/Validations' let RegisterPageThree = ({handleSubmit,onSubmit,prevPage}) => { const validateConfirmPassword = (password) => Register/RegisterPageThree.js The RegisterPageThree component includes two password fields. Added validation that both passwords should match.
  • 24. password && password !== props.password ? VALIDATE_CONFIRM_PASSWORD : undefined return ( <View> <Field name="password" component={FormInput} placeholder={“Enter Password”} validate= {[passwordRequired,validatePassword]} /> <Field name="confirmPassword" component={FormInput} placeholder={“Re Enter Password”} validate= {[passwordRequired,validateConfirmPassw ord]} />
  • 25. <CustomButton buttonLabel={“Back”} onPress={prevPage}/> <CustomButton buttonLabel={“Next”} onPress={handleSubmit(nextPage)}/> </View> ) } RegisterPageThree = reduxForm({ form: 'register-form', destroyOnUnmount : false, forceUnregisterOnUnmount : true })(RegisterPageThree) const selector = formValueSelector('register-form') export default RegisterPageThree = connect(state => { const password = selector(state, 'password') return {password} })(RegisterPageThree)
  • 26. Register/action.js export const signupUser = user => ({ type: 'REGISTER_REQUEST', payload: user, }); Register/saga.js import {put, takeLatest} from 'redux- saga/effects'; import {userSignup} from 'api/Signup'; function* signupUser({payload}) { try { const response = yield userSignup(payload); yield put({type: 'REGISTER_SUCCESS', response}); } catch (error) { yield put({type: 'REGISTER_FAILURE',
  • 27. error: error.message}); } } export default function* signupScreenSaga() { yield takeLatest('REGISTER_REQUEST', signupUser); } Explanation On clicking submit button, onSubmit will be called, and signupUser(payload) will be dispatched containing payload. dispatch(signupUser(payload))
  • 28. From the file Register/action.js, the Register action type “REGISTER_REQUEST” will be dispatched. Then saga middleware will watch for the “REGISTER_REQUEST” type action. It will take the latest encounter of that action and call the register API. For a successful call, it will dispatch the “REGISTER_SUCCESS” action with response data. For a Fail call, it will dispatch the “REGISTER_FAILURE” action with an error message.
  • 30. Open store/reducers.js and add this chunk of code stating switch cases This reducer serves actions coming from Login and Register. Both the modules dispatch similar types of actions- 1. Request Action: Upon this action, the reducer updates the loading variable to true. 2. Success Action: Upon this action, the reducer updates the loading variable to false and stores the response from the action to the uservariable. 3. Failure Action: Upon this action, the reducer updates the loading variable to false and stores response coming from action to error variable
  • 31. const AuthReducer = (state = initialState, action) => { switch (action.type) { case 'REGISTER_REQUEST': return { ...state, loading: true, }; case 'REGISTER_SUCCESS': return { ...state, user: action.response, loading: false, }; case 'REGISTER_FAILURE': return { ...state, error: action.error, loading: false, }; store/reducers.js
  • 32. case 'LOGIN_REQUEST': return { ...state, loading: true, }; case 'LOGIN_SUCCESS': return { ...state, user: action.response, loading: false, }; case 'LOGIN_FAILURE': return { ...state, error: action.error, loading: false, }; default: return state; } };
  • 34. The Login page accepts two inputs- email and password. Login API is called on clicking onSubmit Button. After successful login Dashboard screen will appear. Login/index.js import React from 'react' import { Field, reduxForm } from 'redux- form' import { useDispatch } from 'react-redux' import { View, ScrollView } from 'react- native' import { loginUser } from './actions' import { FormInput, CustomButton } from 'components' import { passwordRequired, emailRequired, validatePassword , validateEmail } from 'utils/Validations' const Login = (props) => {
  • 35. const dispatch = useDispatch() const onSubmit = (values) => dispatch(loginUser(values)) return ( <ScrollView> <Field name="email" component={FormInput} placeholder={“Enter Email”} validate={[emailRequired,validateEmail]} /> <Field name="password" component={FormInput} placeholder={“Enter Password”} validate={[passwordRequired,validatePassword]} /> <CustomButton buttonLabel={“Login”} onPress={props.handleSubmit(onSubmit)} /> </ScrollView> ) } export default reduxForm({ form: 'login-form' })(Login)
  • 36. Login/action.js export const loginUser = (user) => ({ type: "LOGIN_REQUEST", payload: user, }); Login/saga.js import {put, takeLatest} from 'redux- saga/effects'; import {userLogin} from 'api/login'; function* loginUser({payload}) { try { const response = yield userLogin(payload); yield put({type: 'LOGIN_SUCCESS', response}); } catch (error) { yield put({type: 'LOGIN_FAILURE', error: error.message});
  • 37. } } export default function* loginScreenSaga() { yield takeLatest('LOGIN_REQUEST', loginUser); } Explanation On clicking the submit button, onSubmit will be called, and loginUser(values) will be dispatched containing the user email and password. const onSubmit = (values) =&gt; dispatch(loginUser(values))
  • 38. From the file Login/action.js, the Login action type “LOGIN_REQUEST” will be dispatched. Then saga middleware will watch for the “LOGIN_REQUEST” type action. It will take the latest encounter of that action and call the login API. For a successful call, it will dispatch the “LOGIN_SUCCESS” action with response data. For a Fail call, it will dispatch the “LOGIN_FAILURE” action with an error message.
  • 40. const API_KEY = '' //put your key here const endpoint = { login : `https://identitytoolkit.googleapis.com/v1/accou nts:signInWithPassword?key=${API_KEY}` } export const userLogin = async (user) => { const response = await fetch(endpoint.login,{ method: 'POST', headers: { 'Content-Type' : 'application/json' }, body: JSON.stringify({ email: user.email, password: user.password, returnSecureToken: true }) }) if(!response.ok) throw new Error('Something Went Wrong!!'); const responseData = await response.json() return responseData.email } api/login/index.js
  • 42. import React from 'react'; import {useSelector} from 'react-redux'; import {scale, verticalScale} from 'react- native-size-matters'; import {Text, StyleSheet, SafeAreaView} from 'react-native'; import Colors from 'utils/Colors'; const DashBoard = () => { const userEmail = useSelector(state => state.Auth.user); return ( <SafeAreaView style={styles.screen}> <Text style={styles.hiText}>Hii, there</Text> Once you are successfully logged in, you’ll be redirected to the dashboard page. Here’s the code for the UI. Dashboard/index.js
  • 43. <Text style={styles.name}>{userEmail} </Text> </SafeAreaView> ); }; export default DashBoard; useSelector() allows you to extract data from the Redux store state, using a selector function, so that we can use it in our component. As you can see, we can get the value of the user’s email address from state.Login.user. You can find the entire source code of the demo application at Github Repository, from where you can clone and play around with code.
  • 45. So, this was about implementing redux-saga with your redux-form in React Native application. We have covered complete authentication using redux-form features Field Array, Wizard Form, and redux- middleware. You can visit the React Native Tutorials page for more such tutorials and clone the github repository to experiment. If you are looking for a helping hand for your React Native application, please contact us today to hire React Native developers from us. We have experienced and skilled developers having fundamental and advanced knowledge of React Native.