Useful React tips and practices

State management

Every React component (both class and functional) can have a state. A state is basically a JavaScript object that represents the part of a component that can change. Typically, a change in a component state affects other components. Using local state is fine when working with simple or lightweight apps. But not efficient with huge applications. Having a global state management is ideal when working on complex applications. Combining React’s context API with state, you can easily implement global state management without using 3rd party libraries like Redux. Here is a simple example

Reducers/useReducer

Personally, i don’t think the term reducer does a great job describing what it does. Think of a reducer as a function that manages changes to an object (in this case the state).

The useReducer hook is used as an alternative to useState. Especially when you have a complex state logic or when the next state depends on the previous one. It accepts a reducer function, and returns the current state paired with a dispatch method.

Functional vs Class Components

Class components used to be the only way to create dynamic components with state, but that changed since the introduction of react hooks. Functional components are better than class components in a number of ways (in my opinion). First, it is easier to test because its a just plain JavaScript function that returns an element. In terms of performance, both depends on how you write the code or whats actually going on, but functional components have seen a performance boost with hooks. I also think class components involves more steps and more lines of code than a functional component. Compare the following snippets and draw conclusions

It is still useful to know how to define components using either methods. More useful to know how to convert life cycles to hooks and vice versa. Might come in handy at some point. Read more from:
https://reactjs.org/docs/components-and-props.html

https://reactjs.org/docs/state-and-lifecycle.html

Error Boundaries

Error boundaries are React components that catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI

Basically it prevents an error in a part of the UI from breaking the entire app. I really wish i knew this earlier. Its like try/catch blocks but for components.

Error boundaries catch errors during rendering, in life cycle methods, and in constructors of the whole tree below them. This means it can only be written as a class component and has to be used at the top level of your application tree where you want to catch errors.

Components or not

Deciding what part of your application should be a component of its own can be tough at times for people new to React. Apply the single responsibility technique — that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller sub components. Easiest and fastest way i find is to first build a static version of your application with no interactivity. Next find out the parts that are complete on its own and can change overtime as well as the parts that are reused in the entire application. Break those parts identified into sub components and add state and functionalities. Checkout this article — thinking in react

If you liked this article, please hit the claps. Drop your feedback in the comments too. If there are other useful tips or practices you know please share in the comments. If there is something that isn't really useful here, do let me know. Thanks

Software engineer and AI enthusiast.