Concepts to become an advanced React developer
Increase you react level by using these techniques!
We all love ReactJS. It is one of the best and popular way to create SPA(Single Page Application). It offers flexibility and facility. It has great feature to use it to create a single component in the existing website or use it to create the whole website from scratch.
Now ReactJS is a framework used by many other frameworks or toolkits such as NextJs, GatsByJs, Razzle, AfterJs etc. So becoming a better ReactJS developer will in turn help you to better use these frameworks.
Use Fragment instead of div
Many times we want to hold multiple components and as render allows only one component to return, we use div tag to contain all of our components. This add an extra HTML element in our document.
According to the official guide,
Sometimes we break HTML semantics when we add
<div>
elements to our JSX to make our React code work, especially when working with lists (<ol>
,<ul>
and<dl>
) and the HTML<table>
. In these cases we should rather use React Fragments to group together multiple elements.
import React, { Fragment } from 'react';
function ListItem({ item }) {
return (
<Fragment>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
);
}
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
<ListItem item={item} key={item.id} />
))}
</dl>
);
}
For more info, see the Fragments documentation.
Use context more
As the officials say about it, Context provides a way to pass data through the component tree without having to pass props down manually at every level.
So if you have multiple components that needs a value then use context. If you have only a single child component that needs this value use compositions.
one example to set theme from the official docs,
theme-context.js
export const themes = {
light: {
foreground: '#000000',
background: '#eeeeee',
},
dark: {
foreground: '#ffffff',
background: '#222222',
},
};export const ThemeContext = React.createContext(
themes.dark // default value
);
themed-button.js
import {ThemeContext} from './theme-context';class ThemedButton extends React.Component {
render() {
let props = this.props;
let theme = this.context;
return (
<button
{...props}
style={{backgroundColor: theme.background}}
/>
);
}
}
ThemedButton.contextType = ThemeContext;export default ThemedButton;
app.js
import {ThemeContext, themes} from './theme-context';
import ThemedButton from './themed-button';// An intermediate component that uses the ThemedButton
function Toolbar(props) {
return (
<ThemedButton onClick={props.changeTheme}>
Change Theme
</ThemedButton>
);
}class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: themes.light,
};this.toggleTheme = () => {
this.setState(state => ({
theme:
state.theme === themes.dark
? themes.light
: themes.dark,
}));
};
}render() {
// The ThemedButton button inside the ThemeProvider
// uses the theme from state while the one outside uses
// the default dark theme
return (
<Page>
<ThemeContext.Provider value={this.state.theme}>
<Toolbar changeTheme={this.toggleTheme} />
</ThemeContext.Provider>
<Section>
<ThemedButton />
</Section>
</Page>
);
}
}ReactDOM.render(<App />, document.root);
Have at least one Error Boundaries
React 16 comes with an amazing feature Error Boundaries. As the name suggests, It bounds the error of all the child components. The idea is very simple. Create a React component and use it as parent wherever you want to handle the errors. If there is any error in your child component then your Error Boundary component will be called to handle the error.
Keep in mind that rendering error are handled using error boundaries. Imperative errors such as in Event handlers should be handled using javascript try/catch blocks.
Use componentDidCatch()
to log error information.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}componentDidCatch(error, info) {
// You can also log the error to an error reporting service
logErrorToMyService(error, info);
}render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}return this.props.children;
}
}
Then you can use it as a regular component:
<ErrorBoundary>
<MyWidget />
</ErrorBoundary>
If the ErrorBoundary component has an error in itself then it cannot handle it 😐.
The feature was there in React 15 named unstable_handleError.
This method no longer works, and you will need to change it to componentDidCatch
in your code starting from the first 16 beta release.
For this change, React has provided a codemod to automatically migrate your code.
Use production build in LIVE environment
Official site has listed many configurations which can increase your performance. Don’t forget to check them out before deploying to the LIVE environment.
Check out the guide here, reactjs.org/docs/optimizing-performance
It will take merely 10 minutes to configure and will give amazing performance boost to your app.
Use Refs to interact with child
We can use Refs to trigger animation, text selection or manage the focus.
For example,
To set focus in React, we can use Refs to DOM elements.
Using this, we first create a ref to an element in the JSX of a component class:
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// Create a ref to store the textInput DOM element
this.textInput = React.createRef();
}
render() {
// Use the `ref` callback to store a reference to the text input DOM
// element in an instance field (for example, this.textInput).
return (
<input
type="text"
ref={this.textInput}
/>
);
}
}
Then we can focus it elsewhere in our component when needed:
focus() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
this.textInput.current.focus();
}
For more info, see programmatically-managing-focus.
Use code splitting
If you’re using CRA(create react app) or NextJs then there will a webpack configuration file already. It will create a single file(bundle) which will contain your whole app. Now if you use third party libraries or your app becomes larger then your bundle file will also be larger. When a user comes to the website then browser will download the whole bundle file and then render the website. This can slow your website drastically so code splitting allows the generated to split and create multiple outputs. So the browser will load the appropriate bundle when it needs it. In turn improving the site load up time.
We can use React.lazy to achieve this,
Official Note:
React.lazy
and Suspense is not yet available for server-side rendering. If you want to do code-splitting in a server rendered app, we still recommend React Loadable. It has a nice guide for bundle splitting with server-side rendering.
You can split your code in various ways but a good starting point is based on routes,
Most people on the web are used to page transitions taking some amount of time to load. You also tend to be re-rendering the entire page at once so your users are unlikely to be interacting with other elements on the page at the same time.
Here’s an example of how to setup route-based code splitting into your app using libraries like React Router with React.lazy
.
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);
Suspense is nothing but a fallback mechanism. if the required bundle is not loaded yet then it will be shown. You can add a your spinner here to show loading sign to your users.
You can even use ErrorBoundary as parent to Suspense to handle other error such as network error!
React.lazy
currently only supports default exports. So if you want to use it with named exports, check out named-exports.
Static Type Checking
Javascript is not typed language and many of the problems arise due to wrong types.
we can use various type checkers available in the market But one famous and beginner friendly tool is Flow. It is developed at Facebook and is often used with React. It lets you annotate the variables, functions, and React components with a special type syntax, and catch mistakes early. You can read an introduction to Flow to learn its basics. step by step instructions are given in this official react guide.
Bonus tip
Ensure that your web application can be fully operated with the keyboard only,
Thank you for reading!
Please leave comments if you have any suggestion/s or would like to add a point/s or if you noticed any mistake/typos!
P.S. If you found this article helpful, clap! 👏👏👏 [feels rewarding and gives the motivation to continue my writing].
For more information,
check out the Advanced guide on official guide, https://reactjs.org/docs/getting-started.html