React is a popular library for creating web apps and mobile apps.
In this article, we’ll look at some tips for writing better React apps.
Add Dynamic Class to Manual Class Names
We can add dynamic classes with template string.
For instance, we can write:
className={`foo bar ${this.state.something}`}
where this.state.something
is a string.
Also, we can use the classNames
package to make setting classes dynamically easier.
For instance, we can write:
render () {
const btnClass = classNames({
'btn': true,
'btn-pressed': this.state.isPressed
});
return <button className={btnClass}>click me</button>;
}
We call the classNames
function that comes with the package and then we can set the conditions for adding the classes as the value.
The class name is in the key.
Trace Why a React Component is Re-rendering
We can write our own code to trace why a React component is re-rendering.
In a class component, we can check what values are rendered within the componentDidUpdate
lifecycle method.
As its name suggests, it runs when the component is updated.
For instance, we can write:
componentDidUpdate(prevProps, prevState) {
for (const [key, val] of Object.entries(this.props)){
prevProps[key] !== val && console.log(`prop '${key}' changed`)
}
if(this.state) {
for (const [key, val] of Object.entries(this.props)){
prevState[key] !== val && console.log(`state'${key}' changed`)
}
}
}
We loop through the key-value pairs of the props and state and see what has changed.
We only log if there’re previous props or state.
If we’re using function components, we can create our own hook to log what’s changed.
For instance, we can write:
function useUpdate(props) {
const prev = useRef(props);
useEffect(() => {
const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
if (prev.current[k] !== v) {
ps[k] = [prev.current[k], v];
}
return ps;
}, {});
if (Object.keys(changedProps).length > 0) {
console.log(changedProps);
}
prev.current = props;
});
}
function App(props) {
useUpdate(props);
return <div>{props.children}</div>;
}
We created the useUpdate
gook that use the useRef
hook to get the previously stored values of the props.
Then we listen for changes to everything with the useEffect
hook.
We get the changed props by looping through the props and then comparing them with the previous props we got from the useRef
hook.
The props
parameter has the latest props and prev
has the previous props.
Then in our React component, we called our useUpdate
hook with the props.
Difference Between <Route exact path=“/” /> and <Route path=“/” />
The exact
prop lets us distinguish several paths that have similar names.
For instance, we can write:
<Switch>
<Route path="/users" exact component={Users} />
<Route path="/users/create" exact component={CreateUser} />
</Switch>
to distinguish between the /users
and /users/create
routes.
If we don’t have exact
, then /users/create
will be matched with the /users
route.
Loop and Render elements in React.js Without an Array of Objects to Map
If we want to render an object’s properties to a list, we can use the Object.entries
and array’s map
methods.
For instance, we can write:
render() {
return (
<div>
{obj && Object.entries(obj).map(([key, value], index) => {
return <span key={index}>{value}</span>;
}.bind(this))}
</div>
);
}
In our render
method, we used Object.entries
to get the key-value pairs of the object as an array.
Then we called map
to render each property value into a span.
Display Loading Screen While DOM is Rendering
We can display a loading screen by setting the loading state in a component.
For instance, we can write:
import React, { useState, useEffect } from 'react';
const App = () => {
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => setLoading(false), 1000)
}, []);
return !loading && <div>hello world</div>;
};
We have the loading
state and setLoading
function returned by the useState
hook.
We set it to true
initially to see our loading message.
Then we use the useEffect
hook to set the loading
state to false
as the content is loaded.
Then we can render the content we want when the loading
state is false
.
Conclusion
We can use the exact
prop in React Router to match the routes exactly.
We can set a loading state to make it display.
Dynamic classes can be set with string interpretation of the classnames
package.
We can watch for props and state changes in our components to see why our component is re-rendering.