Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Following my article on an intuitive, boilerplate-free global state solution for React, I decided to put real data behind the concept. I started with a bare-bones example of a React application that harnesses Redux for global state management, and I converted it to ReactN. During this process, I measured objective changes in memory allocation and bundle size. A thorough analysis and source code is provided on GitHub, but I will summarize here, as well as walk through how easy a conversion is and how much simpler the refactored code becomes.
You may use ReactN yourself via reactn on NPM or contribute to, fork, or otherwise spy on the open-source GitHub repository.
The Application 0ïžâŁ
The application is a showcase of global state features. On mount, the application fetches a page and stores the response in the global state. On render, a button displays a number from the global state. When the button is pressed, the number increments.
This isnât breath-taking functionality. This is a demonstration of the three most important aspects of global state: the ability to read from it, the ability to write to it, and the ability to manage it asynchronously.
There are four parts to establishing a global state in React, and we will walk through each of them: the dependencies, initializing the global state, connecting the components to the state, and reading from and writing to the global state.
The Redux Application 1ïžâŁ
The Dependencies đ¶đ¶đ¶
We need three packages to establish our Redux application: redux, which contains the logic to create and interact with the global state; react-redux, which contains React logic and higher-order components for integrating the global state with a React application; and redux-thunk, a Redux middleware for processing asynchronous state modifications.
Initializing the Global State đŹ
To initialize the global state, we use the createStore function from the redux package. To it, we pass the desired reducers and middleware.
The end result looks like this:
The createStore function is quite the enigma, but I wonât spend this article discussing common developer complaints about Reduxâs learning curve!
Connecting the Components đ
In order to connect the components to the state, we must wrap the application in a global state context provider, then wrap each connected component in a higher-order-component that behaves as a global state context consumer.
The end result looks like this:
Thatâs a lot of code just to use global state. Despite the react-redux package being geared towards integrating Redux with React, I personally do not feel the above has a React-first approach in mind. But I wonât spend this article discussing common developer complaints about Reduxâs boilerplate!
While this step includes the mysterious actions fetchData and incrementX, I included them in the next section, as they are directly related to writing to the global state.
Reading from and Writing to the Global State đâđš
With all of that boilerplate out of the way, we can finally use the global state! We access and modify the state through the connected componentâs props.
The end result looks like this:
Actions aside, the component itself is very easy to read!
The ReactN Application 2ïžâŁ
Now that weâve seen the familiar Redux implementation, letâs see how we can decrease the complexity above and turn it into a more readable, more intuitive React application.
The D̶e̶p̶e̶n̶d̶e̶n̶c̶i̶e̶s̶ Dependency đ¶
Install the reactn package. There is no asynchronous middleware. ReactN supports Promises out-of-the-box. You can remove the three aforementioned Redux dependencies and sigh in relief as your application drops by 213 dependency files and has a 13% smaller production bundle size when it uses ReactNÂ instead.
Initializing the Global State đŹ
The first of the cumbersome boilerplate, time to initialize the store and establish the reducers. Reducers and actions are optional in ReactN. I only include them here for a fair comparison, as we are using them in Redux. If you find reducers to be too much boilerplate, you are more than welcome to abstain from using them. A reducer-free alternative is provided later.
We use setGlobal to literally just set the global state. Great for initializing.
We use addReducer to add a reducer. Note that ReactN does not use actions. We call the reducer directly!
Weâve reduced the boilerplate from 640 bytes to 330 while including actions! More on that laterâââfor this project, I wouldnât create a fetchData reducer at all. I only include it here for symmetry with the Redux application.
Connecting the Components đ
ReactN does not use higher-order components. To connect you components to the global state, you add one byte to your file.
I added an n to the end of the package name, changing react to reactn. That was it. Your Components and PureComponents now have access to the global state.
That was 728 less bytes of boilerplate! One less app-wide HOC and one less HOC per component.
Reading from and Writing to the Global State đâđš
How do we use the global state if we didnât tell it what props we want on our component? With React in mind, ReactN treats the global state as a member variableâââexactly as you are used to using with local stateâs this.state.
The component looks exactly the sameâââexcept to access the global state, you use the this.global member variable instead of props. No higher-order component required!
Thatâs it! The component is done. Itâs fully functional.
fetchData đ¶
I mentioned how I would handle the fetch data action differently with ReactN, so I will elaborate here. ReactN is not limited to actions and reducers, like Redux. ReactNâs global state member variable is meant to behave exactly like Reactâs innate local state member variable, and that includes an analogous this.setGlobal method that behaves like this.setState. The setGlobal method has additional functionality of supporting JavaScript Promises.
Unless fetchData is being called across multiple components, it doesnât afford us much to name it as a reducer, so I would simply call setGlobal instead:
Fetch index.html, parse the text, create the state object, and set it.
I wouldnât be opposed to the incrementX reducer simply being a method on the component that calls setGlobal either, since it isnât being shared across components either.
One Last Comparison đ
I wanted to show the two applications, side-by-side, in their completed state, since the above really only covers snippets. The code below would be better served if it were split into multiple files, but the real issue is reading, writing, comprehending, and maintaining this code. This applies not only to you, the reader, but your team, which is often comprised of junior developers.
Before: index.js with Redux đŽ
After: index.js with ReactNÂ đ
Before: App.js with Redux đŽ
After: App.js with ReactNÂ đ
The Cold, Hard Fact â
Whether you believe one method is easier to read than another, one thing here is objective. The above application in a production build is 531,736 bytes using ReactN. Itâs Redux counterpart is 611,990 bytesâââa 15% increase.
The difference likely drops with scope, as a project re-uses more actions, and contains significantly more logic unrelated to global state. However, with an increase in scope, you see an even greater reduction in boilerplate!
Conclusion đ
If you want to contribute to this project, it is open-source on GitHub, and I would be absolutely ecstatic for more community feedback. If you want to play around with this project, simply npm install reactn --save or yarn add reactn.
If you liked this article, feel free to give it a clap or two. Itâs quick, itâs easy, and itâs free! If you have any questions or relevant great advice, please leave them in the comments below.
To read more of my columns, you may follow me on LinkedIn and Twitter, or check out my portfolio on CharlesStover.com.
Replacing Redux with ReactN to reduce complexity and bundle size was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.