Developer 1 and Developer 2 were fighting over which state management tool is better- Redux or Context API. They both listed pros and cons but sadly none realized the actual use case and purpose of Redux and Context API.
If you’re one of the developer 1 or 2, then continue reading the tutorial to learn why it shouldn’t be Redux vs Context API.
If you’re having a Javascript background then you might be familiar with the terms Redux and Context API. And probably, you might have come across so many blogs that debate on which is better- Redux vs Context API. I assumed the same unless I realized it’s not!
After reading a bunch of blogs, I concluded the purpose of both the tools and how different they are from each other. If you aren’t aware yet, don’t worry this tutorial will help you understand the use cases of both tools with a basic demo example. Here, we will build an app using both approaches and discuss them.
Let’s get started, then!
According to documentation-
Redux is a pattern and library for managing and updating application state, using events called “actions”. It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.
The documentation clearly mentions that redux is for “managing state” and understanding how the state is updated.
Redux is mainly used to manage the state of React applications in a centralized place where to access the state anywhere in the application. Technically, The concept of Redux is based on Flux architecture and this concept isn’t restricted to React apps; there are implementations in different technologies, as well (e.g. NgRx for Angular). But Redux is particularly implemented with React.
It consists of mainly four building blocks:
1. Reducer: These are functions with state and actions passed in as arguments. It contains “action.type” in switch cases which returns the changed value. It optionally accepts the payload (generally created in a separate file known as reducers.js)
2. Store: Store is the collection of all data. You can pass it to the provider.
3. Provider: A React component that accepts store as an argument (usually created in index.js)
4. Actions: Functions that provide/return action type and payload to the dispatcher which will further call the respective reducer (generally created in a separate file known as actions.js)
React documentation explains context API as-
Context provides a way to pass data through the component tree without having to pass props down manually at every level.
In a typical React application, data is passed top-down (parent to child) via props, but such usage can be cumbersome for certain types of props (e.g. locale preference, UI theme) that are required by many components within an application. Context provides a way to share values like these between components without having to explicitly pass a prop through every level of the tree.
If you can observe the documentation states context for “passing” and “sharing” values and mention nothing about “managing the state”
The main purpose of using context API is avoiding ‘prop drilling’ – passing prop at every level. It is more like a pipeline used to pass values from one end to another.
Context API provides the easiest way for passing data through the component tree so that you don’t have to pass props down manually at every level. For example, assume we have a component tree consisting of A, B, C, and D components. Now you need to pass props from A to D, so rather than passing it A > B > C > D,i.e., to every component, with the help of context you can directly pass to A > D.
Now, many blogs have mentioned that Context API is the best replacement for Redux because it’s in-built and you don’t have to install dependencies for the same. Is this really true- Can Context API replace Redux? We will discuss this in a further section. Stay tuned to explore!
We can divide the Context API into three blocks:
1. Context: Use createContext() function that takes the default value as a first argument. Here it is optional to pass a Javascript object. You can implement multiple contexts in your app.
2. Provider: After creating context, the Provider provides the capability for accessing the context. It provides functions & data to pass values further to the component.
3. Consumer: Consumer allows access to the value to child components which are wrapped by Provider. It has two types-
• one for changing the counter value
• two for each of the buttons.
The initial setup would be the same for both Context and Redux approaches.
Are you struggling to choose between the Context and Redux approach and implement it in your application?
Get in touch with the best React Native App Development Company, who have the developers with such expertise to make the implementation hustle-free and painless.!
Initially, create a react native app using the following command
Install Required dependencies for Redux
We will create our store within our App.js file.
// App.js
import React, { Component } from 'react'; import { Provider } from 'react-redux'; import { createStore } from 'redux'; import totalReducers from './reducers/index.js'; import Counter from './components/counters'; const store = createStore(totalReducers); export default class App extends Component{ render(){ return(); } }
Reducers return the data required by the application. In this demo, the reducer will return the updated counter value. Here is our counterReducer.js file inside the reducers folder.
// reducers/counterReducer.js
let count= 0; export default (state = count , action) => { switch (action.type) { case "Increment": count ++ break; case "Decrement": count -- break; default: count; } return count; }
Explanation
// reducers/index.js
import {combineReducers} from 'redux'; import counterReducer from './counterReducer'; const totalReducers= combineReducers({ count: counterReducer, }); export default totalReducers;
Explanation
Create two actions: Increment & Decrement.
// actions/index.js
export function increment(){ return{ type: "Increment" }; } export function decrement(){ return{ type: "Decrement" }; }
We will simply create only one component called a counter component. For using reducers and actions, we have to implement these functions:
Note: Keep in mind how we assigned names to reducers in the combineReducers function because we have to use the same name for calling respective reducers.
function mapDispatchToProps(dispatch){ return bindActionCreators({increment, decrement}, dispatch) }
Note: bindActionCreators function simply combines our actions into one object.
Moving towards the component that manages the user interface.
// component/counter.js
class Counters extends Component { constructor(props) { super(props); } render() { return (); } } function mapStateToProps(state) { return { count: state.count, }; } function mapDispatchToProps(dispatch) { return bindActionCreators({increment, decrement}, dispatch); } export default connect(mapStateToProps, mapDispatchToProps)(Counters); {'The Redux Approach'} {this.props.count} this.props.increment()}> Increment + this.props.decrement()}> Decrement -
For styling your component you can use the below code
const styles = StyleSheet.create({ mainContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', }, counterNumber: { fontSize: 35, fontWeight: 'bold', }, buttonContainer: { flexDirection: 'row', }, buttonStyle: { backgroundColor: 'green', borderWidth: 1, height: 30, width: '25%', borderRadius: 5, justifyContent: 'center', alignItems: 'center', }, });
So far we are done with redux set up, logic, and user interface for the counter demo. Now, just a simple step remaining – import our App file in our index.js file.
// index.js
import {AppRegistry} from 'react-native'; import App from './src/App.js'; import {name as appName} from './app.json'; AppRegistry.registerComponent(appName, () => App);
Git Repo link: https://github.com/sunil-bacancy/CounterDemo
Since the context API is in-built functionality we don’t need to install third-party dependencies.
Create a folder src at the root of your app. Within the src folder, we have to create 3 folders that are reducers, components, state and one file App.js.
Just like Redux, declare reducer with Context API.
// reducers/globalReducer.js
export default countReducer = (state , action) => { switch (action.type) { case "Increment": return{ ...state, counter: state.counter + 1, } case "Decrement": return{ ...state, counter: state.counter - 1, } default: return{ state } } }
// state/globalState.js
import React, {createContext, useReducer} from 'react'; import countReducer from '../reducers/globalReducer'; const initialState = { counter: 0 } export const GlobalContext = createContext(initialState); export default GlobalProvider = ({children}) => { const [state, dispatch] = useReducer(countReducer, initialState); return({children} ) }
After creating the context, we need to provide the context so that it is accessible in the child components. For that, you need to wrap it within the Provider.
// src/App.js
import React, { Component } from 'react'; import GlobalProvider from './state/globalState'; import Counters from './components/counter'; export default class App extends Component { render(){ return () } }
Use useContext() for consuming the context in respective child components.
// components/counter.js
import React, { Component, useContext } from 'react'; import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; import {GlobalContext} from '../state/globalState'; const Counters = () => { const {state} = useContext(GlobalContext); const {dispatch} = useContext(GlobalContext); return() } export default Counters; {'The Context API Approach' } { state.counter } dispatch({type: "Increment"})} > Increment + dispatch({type: "Decrement"})} > Decrement -
For styling your component you can use the below code.
const styles = StyleSheet.create({ mainContainer: { flex: 1, justifyContent: 'center', alignItems: 'center' }, counterNumber: { fontSize: 35, fontWeight: 'bold' }, buttonContainer: { flexDirection: 'row' }, buttonStyle: { backgroundColor: 'green', borderWidth: 1, height: 30, width: '25%', borderRadius: 5, justifyContent: 'center', alignItems: 'center', }, })
Git Repo link: https://github.com/sunil-bacancy/CounterContextDemo
I hope the tutorial helped you understand how different Context and Redux are. Moreover, try to implement both the approaches and play around with the code to dig deeper. For more such React Native tutorials, we have a React Native Tutorials page that consists of step-by-step guidelines with the github source.
I can understand how difficult it can be to organize and manage a global store for a complex application, and also how precise you need to be for implementing Context API in your application. In case you have a large and complex project and want to implement Redux or Context API then feel free to contact us and hire React Native developer.
Your Success Is Guaranteed !
We accelerate the release of digital product and guaranteed their success
We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.