It’s common these day when React & React Native developers use State management library (like Redux). I’ve been using React & React Native for a while now and found out that Pure React is actually not bad. In this article I will share my way of doing things with React & React Native purely, without State management library (represented by Redux).
For those of you who are struggling learning Redux, because of the overwhelming of the whole React/JSX/Babel/Webpack/Native Component/Native Module/.. and have to add Redux to the list just to solve some of React problems, or because of the high learning curve of Redux, I hope you find this article helpful.
Assuming you have some knowledge of React, I will jump right in the problems that most of us encoutered at the beginning of time learning React:
- Flow
pass data down, pass event up
makes us to pass data & function via props and it's hard to manage when amount of props gets huge. (Comunication between component Parent - Child ) - Another problem when passing data & function via props is the comunication of components not in same tree component.
- Sync data between component that share common information.
Solution? Redux ? Not so fast. People often come to Redux as it's the only way. Redux solves these problems quite well, but it come with alot of things and they make it hard to learn and apply. In this article, I will share 2 ways of approach with some tools to use in each situations.
Global Store is one of Redux's fundamental principles. It can be done only using React.
context
is rarely mentioned when people talking about React. With context
you can communicate between parent component and child components without passing data & function via props (and props of components in the middle). You can read more about context
here. The implementation flow with context
will be:
- Declare context in Highest Level Component (Call as Root )
- Create a method in Root that can get/set
state
. - Pass method via
context
- Declare to receive
context
in Child Components and we just have to use this method to get/setstate
in Root. - All necessary information will be store in
state
of Root. When it changes, Root will re-render and UI will be updated.
Example Code: https://gist.github.com/lequanghuylc/2d9c0ff12c6ac64557c0acb4a0987ff1
Warming about using context
: Facebook doesn't encourage us to use context, because It is an experimental API and it is likely to break in future releases of React
, and if we dont use it right, it would be a mess. But let's pause for a second and look at famous libararies:
react-redux
usescontext
(a tiny amount)react-router
usescontext
react-navigation
usecontext
- Some UI library uses
context
Although it's not much but context
is still be used. You just have to find a way to use it right. While wrapping it inside Root and Child, you won't work directly with context
(this.store instead), and if context
gets removed in future releases, we can easily update 2 files Child and Root (with other solution right below) and it's done.
This solution can totally be a replacement for context
, and it's more powerful because it can communicate outside of React scope, between React Applications (in case you mix React with other frontend library in your website).
The implemention flow of export method setState
will be:
- Create a class BaseComponent
- Declare a
static
variable forBaseComponent
- In
componentWillMount
, refer thatstatic variable
to a new function that can get/set state - Rewrite that
static variable
so it can work with many instances. (instances can be managed via id) - Extends all component with
BaseComponent
, then you can import it and directly call thatstatic variable
to get/set state (ofcouse this component has to be mounted first).
With this solution, we can manage all components from anywhere. If we want to follow Global Store Principle, just manage Root component.
Example code: https://gist.github.com/lequanghuylc/128ad8d8822d00c632a26e2737a75b81
service
simply is some kind of code running under UI (headless) to do some small task assigned to it. Using service
help you separate app logic handling and app's UI.
The implementation flow with service
will be:
- Don't handle logic in UI Component.
- Create
service module
that can run independently & headlessly.service
can be use for implementing app features (like server API wrapper, sockets, local DB, native functions). - any data return from
service
will send to component to update UI. We can useevent listener
for that.
One example of service
is firebase
. When using firebase database
, we dont know about token
or something like that. Because firebase
doesnt return this information and we doesn't need to know. Everything unnessary will be kept internally. firebase database
only provide data
, the way to CRUD data
and some listener
to notify when data
is changed.
We can totally build a service
like that to communicate with Server via API. Here is some example of build a service, using class
& state
for React similarity.
class ServiceAPI {
constructor() {
this.syncData();
}
state = {};
// update state directlly using this.state.something = "something"
syncData = () => {
// sync data with local when re-open app
}
login = (id, pass) => {
// call api or something
// token will be stored in state
}
logout = () => {
}
onLoggedOut = ( callback ) => {
// listener will run callback function when user logged out
}
}
// remember to make it singleton when export (with new keyword)
export default new ServiceAPI();
You can also use directlly event listener
to communicate between components. (Example: Convert Modal component Alert to function). Take a look at react-native-event-listeners & js-events-listener (forked)
2 Approaches in this article is mentioned theoretically. I will update example app as soon as possible, but I think it's kinda clear and easy to apply.
So what's about Redux ?
Redux is another story. As mentioned above, Redux solves the problems quite well, but it comes with alot of things: Architecture (from flux
to redux
), new definitions when implement (action
& reducer
) and the whole ecosystem to develop the Redux way
. I was just simply shared some tips & tools so you can do more with Pure React. You can use it in your own way.
If you know all about Redux & its ecosystem. Well then, nothing keeping you from not using Redux. But keep in mind that we don't have to know all that to do the job. And the problems dont stay in libraries & tools, but in our way of using them.
Let's keep our minds open and think about these. :)
Hi @lequanghuylc thanks a lot for these tips. Just today, I was thinking about another way I can manage Global store without Redux and your article has been useful for me.
Regards :)