8 Miraculous Ways to Bolster Your React Apps
Tags: react, javascript, webdev, node
Published: 2019-08-25 20:41:10


Find me on [medium](https://medium.com/@jsmanifest)

Sometimes when we build our apps in React we can easily miss opportunities to improve our app, and that's probably because when our app just _works_ and _feels_ fast we tolerate it for being perfect. As developers we might assume that if the outcome of our projects look normal to us, then it would look normal to the users. When our minds think that way, this _may_ cause us to overlook areas in our code that can optimized for a better result.

This article will go over 8 Miraculous Ways to Bolster Your React Apps.

## 1. Love Your Identities

The first way to bolster your react apps is to love your identities.

It's important to remember that you can wrap variables and functions with `React.useMemo` as you can grant them the ability to memoize themselves so that react knows they remain identical for future renders.

Otherwise if you don't memoize them, their references will disappear from future renders. This might hurt their feelings, so you can show them that you love them and would like to keep them by memoizing them. If you love them, they'll love you back by making sure they take care of you and your app by helping to avoid wasteful operations for the situations they're in.

For example, let's pretend that we are making a custom hook that takes in a list of `urls` as arguments so that it can accumulate them into an array of promises to be resolved with `Promise.all`. The results will be inserted to the state and passed to the `App` component as soon as it's finished. Our promises list will map over the `urls` array which contains 4 different urls to fetch:

{% gist https://gist.github.com/jsmanifest/45d8660adb8539b27b9d5eae70e5bab7.js %}

Our task was to fetch data from these 4 links, so ideally only 4 requests should be sent out. But if we take a look at the _network tab_ inside _Chrome_, the truth is that it sent out 8 requests. This is because the `urls` argument does _not_ retain the same identity as previously because when `App` re-renders, it's instantiating a new array every time--so React treats it as a changed value.

![react tips using memoizers](https://jsmanifest.s3-us-west-1.amazonaws.com/posts/8-miraculous-ways-to-bolster-your-react-apps/memoize1.jpg)

Computer programs sometimes think they can outsmart us and get away with this lousy behavior. In order to fix this we can use `React.useMemo` so that the array of promises doesn't recompute itself on every render _as long as the array containing the urls does not change_.

Let's refactor our code to apply this concept:

{% gist https://gist.github.com/pfftdammitchris/6f953954340426087e46e5e79c20ee98.js %}

If we run this now, it will still be sending 8 requests. That's because although we memoized the `urls` array, we also need to memoize the `promises` variables inside our hook because _that is also instantiating itself_ whenever the hook runs:

{% gist https://gist.github.com/pfftdammitchris/9a0d611263986e543cbefd5a0ac120d8.js %}

Our code should now only send 4 requests when we run it. Hurray!

![reactjs tips using usememo memoizer](https://jsmanifest.s3-us-west-1.amazonaws.com/posts/8-miraculous-ways-to-bolster-your-react-apps/memoize2.jpg)

## 2. Merge Props to Children

Sometimes we can get in a situation where we want to sneak in a prop to be merged with children before proceeding to render. React lets you view the props of any react element as well as others, such as exposing its `key`.

We can just wrap the children element with a new component and inject the new props from there or we can just merge the new props by using this method.

For example, lets say we have an `App` component that is using a `useModal` hook which provides some handy utilities to manage modals by providing controls like `open`, `close`, and `opened`. We want to pass these props to a `VisibilityControl` component because it's going to provide additional functionality before passing the modal data down to the children:

{% gist https://gist.github.com/pfftdammitchris/40b8ce9e5ccac2d497d0d4d71c69934e.js %}

`VisibilityControl` makes sure that `activated` is `true` before allowing `opened` to be used normally by its children. If this was used in a secret route the `VisibilityControl` provides the functionality of preventing unactivated users from seeing secret content.

## 3. Combine Reducers for a Gargantuan Reducer

There might come a time when you need to combine two or more reducers in the app to make a larger one. This approach is similar to how `combineReducers` worked in react-redux.

Let's pretend we were planning to make a giant microservice app where we originally planned to designate each part in the app to be in charge of their own context/state but then we just thought of a million dollar idea of an app that requires the states to be united into a single large state instead so we can manage them all in the same environment.

We have an `authReducer.js`, `ownersReducer.js`, and `frogsReducer.js` that we'd like to combine:

_authReducer.js_

{% gist https://gist.github.com/pfftdammitchris/004c7ef287e1c005aaa17672fbde9afe.js %}

_ownersReducer.js_

{% gist https://gist.github.com/jsmanifest/776e8c0551a489504ffa23b0e27bc4a4.js %}

_frogsReducer.js_

{% gist https://gist.github.com/jsmanifest/687e8a9603ec6d06f72d63f1ec550040.js %}

We'll import them into our main file and define the state structure there:

_App.js_

{% gist https://gist.github.com/jsmanifest/3723d3d82a70551f29ea635ad27f7e80.js %}

You would then just work with hooks as you normally would with calling `dispatch`, passing in the matching `type` and arguments to the designated reducer.

The most important part to look at is the `rootReducer`:

{% gist https://gist.github.com/jsmanifest/468d7fc4024c127691599649b9c0363f.js %}

## 4. Sentry for Error Reports

Projects benefit immensely from [Sentry](https://docs.sentry.io/platforms/javascript/react/) when integrated with React. Having detailed reports of errors all sent to a central location to be analyzed at once is a _very important_ tool to have!

Once you `npm install @sentry/browser` and have it set up for your react app, you can log into [sentry.io](https://sentry.io) after you create your account and analyze your error reports in your project's dashboard.

These reports are really detailed, so you'll benefit from feeling like an FBI agent by getting fed tons of information to help you solve those errors like knowing the user's device, browser, the URL the error occurred, the user's IP address, the stack trace of the error, was the error handled or not, the function _name_, the source code, a useful list of breadcrumbs exposing a trace of network actions that led to the error, headers, and more.

Here's a screenshot of what this may look like:

![react tips using sentry an error reporting service for react apps](https://jsmanifest.s3-us-west-1.amazonaws.com/posts/8-miraculous-ways-to-bolster-your-react-apps/sentry1.jpg)

You can also have several team members comment on different things so it can also be a collaborative environment.

## 5. Use axios over `window.fetch`

Unless you don't care about Internet Explorer users, you should _not_ use `window.fetch` for your react apps because _none_ of the IE browsers support `window.fetch` unless you provide a polyfill. Axios is great to support IE but also good for the additional functionality it brings to the table like canceling requests mid-flight. This `window.fetch` actually applies to any web app and not specific to React. The reason it's in this list is because it's not uncommon that `window.fetch` is used in React apps today. And since react apps goes through transpiling/compiling stages depending on the tools configured, it can be quite tempting to accidentally assume that it transpiles `window.fetch`.

## 6. Use Callback Refs Over Object Refs When Watching DOM Nodes

Even though `React.useRef` is the new kid on the block for attaching and controlling references to a DOM node, it's not always the best option.

Sometimes you might need more control to a DOM node so that you can provide additional functionality.

For example, the [react docs](https://reactjs.org/docs/hooks-faq.html#how-can-i-measure-a-dom-node) show a situation where you'll need to use a callback ref to ensure that even when there are changes to the current ref value, a component outside can still be notified of updates. This is the advantage of callback refs over `useRef`.

[Material-ui makes use of this powerful concept](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/utils/reactHelpers.js) to attach additional functionality throughout their component modules. The great part about this is that cleanup naturally emerges from this behavior. _Wonderful_!

## 7. `useWhyDidYouUpdate`

This is a custom hook to expose changes that make our components re-render. Sometimes when a memoizer like the higher order component `React.memo` isn't enough you can use this handy hook to find which props you need to consider memoizing instead: (Credits to [Bruno Lemos](https://twitter.com/brunolemos/status/1090377532845801473))

{% gist https://gist.github.com/jsmanifest/a9b2fadc79342b2fcfe75155ce466a25.js %}

You would then use it like this:

{% gist https://gist.github.com/jsmanifest/e0b0fde17d03578b0185923202782efd.js %}

## 8. Make Your Functions Find You

![higher order functions can help save precious and valuable time](https://jsmanifest.s3-us-west-1.amazonaws.com/posts/7-ways-higher-order-functions-can-improve-your-life/2.jpg)

This is going to be quoted from my [previous article](https://codeburst.io/here-are-7-ways-higher-order-functions-can-improve-your-life-a392aa6b29d2) from awhile ago because it's a little long and it fits greatly in this post. Here is the content:

Let me give a real life example as I'd like to put a little more emphasize on this one.

One of the greatest benefits of higher order functions is that when used correctly, it will save _a lot_ of time for _you_ and for _those around you_.

At my job, we used [react-toastify](https://github.com/fkhadra/react-toastify) to display notifications. We used it _every where_. In addition, they also make great escape hatches for quick last minute UX decisions: "How should we handle this error? Just display a toast notification!" Done.

However, we started noticing that when the app became larger and the level of complexity was creeping up on us, our toast notifications were becoming too frequent. This is fine--however, we didn't have a way of preventing duplicates. This meant that some toast notifications were showing up multiple times on the screen even when they were _exactly the same_ as the toast above it.

So we ended up leveraging the api that the library provides to help remove active toast notifications by _id_ using _toast.dismiss()_.

In order to explain the parts ahead, it's probably a good idea to show the file we were importing toasts from before proceeding:

{% gist https://gist.github.com/jsmanifest/0248e0a376b4239b8c11c7f9ce5f6098.js %}

Now bear with me, I know this might not look appealing. But I promise it will get better in two minutes.

This is what we had in a separate component to check if a previous toast was already on the screen. And if there was, it will attempt to remove that toast and re-display the new toast.

{% gist https://gist.github.com/jsmanifest/5f5f08f6241917cb54749f3cd0eb3ab9.js %}

This was working fine--however, we had other toasts throughout the app that needed to be modified the same way. We had to go through every file that displays a toast nofication to remove duplicates.

When we think of _going through every file_ in 2019, we immediately knew that it wasn't the solution. So we looked at the `util/toast.js` file and refactored that to solve our problem instead. Here's what it looked like afterwards:

> src/util/toast.js

{% gist https://gist.github.com/jsmanifest/04127b5a3b191b232f3c40512645714b.js %}

Instead of having to go through every file, the simplest solution was to create a _higher order function_. Doing this allowed us to "reverse" the roles so that instead of us searching through files, the toasts were instead _directed to our higher order function_.

This way the codes in the files were _not_ modified or _touched_. They still function as normal, and we gained the ability to remove duplicate toasts without going anywhere to write unnecessary code in the end. _This saved time_.

## Conclusion

And that concludes the end of this article! I hope you found it useful and look out for more in the future!

Find me on [medium](https://medium.com/@jsmanifest)