S (Single Responsibility Principle)
A class should have only one reason to change.
The Single Responsibility Principle (SRP) in React suggests that each component should have one clear responsibility or role. In other words, a React component should do one thing and do it well.
This principle helps keep your codebase clean and maintainable by ensuring that each component is focused on a specific task. For example, if you have a button component, its responsibility should be limited to rendering the button and handling user interactions. Any unrelated tasks, such as data fetching or state management, should be handled by separate components or modules.
By adhering to the SRP, your React code becomes more organized, easier to understand, and less prone to errors, making it more efficient to develop and maintain.
Let's take a look at this sample code.
const BookList = () => {
const [books, setBooks] = useState<IBook[]>([]);
const fetchBooks = async () => {
try {
const response = await fetch("https://api.com/books");
const data = await JSON.parse(response);
setBooks(data);
} catch (err: any) {
console.log(err.message);
}
};
useEffect(() => {
fetchBooks();
}, []);
return (
<div>
{books?.map((book) => (
<Book title={book.title} image={book.image} key={book.id} />
))}
</div>
);
};
The code seems pretty standard here. What it does is it fetch book data and render it.
Apparently the code violates this principle because the code would have more than one reason to change or more than a single responsibility which are rendering and fetching.
What we can do about it is to simply separate the logic between the rendering and fetching and the component would only receive the final data and doesn't care about the fetching logic.
// useGetBooks.hook.tsx
const useGetBooks = () => {
// We moved the fetching logic into a custom hook
const [books, setBooks] = useState<IBook[]>([]);
const fetchBooks = async () => {
try {
const response = await fetch("https://api.com/books");
const data = await JSON.parse(response);
setBooks(data);
} catch (err: any) {
console.log(err.message);
}
};
useEffect(() => {
fetchBooks();
}, []);
// Return only the final books result
return { books }
}
// BookList.component.tsx
const BookList = () => {
// We call the hook and retrieve the books
const { books } = useGetBooks();
return (
<div>
{books?.map((book) => (
<Book title={book.title} image={book.image} key={book.id} />
))}
</div>
);
};
Now we have two different files which has their own responsibility and it looks neat!
What's next?
Let's not stop here since there are 4 more principles left to learn in SOLID which I will cover in the next article so stay tuned.
Dadah~ 👋
Top comments (1)
Awesome!!!
thank u sir for this great article