Ways to create small components in React

Nawaz
Canadiv’s Technology and Design
3 min readJun 30, 2022

I am working on a project which is basically a web application which is developed using React. In React we make Components which are basically functions that return JSX elements. So it will be a best practice to keep the Component file small which helps us in readability and better understanding of the code. Below are few methods mentioned which helps us in keeping the components small.

Import pure functions

When refactoring a large component, one of the first things I would look for are business logic and functions that are not directly tied to the component state. For example, if you have a helper function in your component that looks like this:

function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

There is no reason to keep that function in the component itself. We can simply move this function into a separate file:

export function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

And import the function into the component:

import { capitalizeFirstLetter } from './stringlib';

Now the function and the business logic within it can be unit tested independently and reused by multiple components. If possible, keep functions pure they are deterministic and very easy to unit test.

Use custom React hooks

React hooks allow developers to do something that wasn’t possible before its introduction — they allow for the abstraction of code that is coupled with component state. For example, if the code in your component looks like this:

const [ customers, setCustomers ] = useState([]);
const [ isLoading, setIsLoading ] = useState(false);
const [ errMessage, setErrMessage ] = useState('');useEffect(() => {
setIsLoading(true); // Calls API to get list of customers
getCustomers().then((response) => {
setCustomers(response.data.customers);
setIsLoading(false);
setErrMessage('');
}).catch((e) => {
setErrMessage(e.message);
setIsLoading(false);
});
}, []);

Much of this code can be moved into a custom hook:

export function useCustomers() {
const [ customers, setCustomers ] = useState([]);
const [ isLoading, setIsLoading ] = useState(false);
const [ errMessage, setErrMessage ] = useState(''); useEffect(() => {
setIsLoading(true); // Calls API to get list of customers
getCustomers().then((response) => {
setCustomers(response.data.customers);
setIsLoading(false);
setErrMessage('');
}).catch((e) => {
setErrMessage(e.message);
setIsLoading(false);
});
}, []); return [ customers, isLoading, errMessage ];
}

The component would simply imported into your component, just like a regular function:

import { useCustomers } from './customerHooks';...const [ customers, isLoading, errMessage ] = useCustomers();

Some additional points about custom hooks:

  • It is perfectly acceptable to have multiple layers of custom hooks to organize complex business logic
  • Custom hooks can be used by multiple components
  • Custom hooks can be unit tested independently with the React testing library

Create child components

Finally, if your component is returning a large chunk of JSX, then it is an indication that you should break the component down into smaller components. This:

return (
<div>
... // a whole bunch of code
{
customers.map((customer) => (
<div>
... // a whole bunch of code
</div>
))
}
</div>
);

could be trimmed down to this:

return (
<div>
... // a whole bunch of code
{
customers.map((customer) => (
<CustomerCard customer={customer} />
))
}
</div>
);

The child component would in turn have its own CSS, imported functions and custom hooks. A child component can also have its own child components and so on. Similar to hooks and functions, components that are small and logically structured can be more easily unit tested.

Keep files small

The React.js framework gives us a lot of tools to keep files small and unit-testable. Take advantage of that!

Hope this blog helps in one way or the other in keeping your components cut to the points and small.

--

--