・This principle states that each component should have only one purpose, meaning it should focus on performing one task effectively. Adhering to SRP makes components easier to understand, test and maintain.
import React, { useEffect, useState } from 'react'
const URL = 'https://jsonplaceholder.typicode.com/todos'
export const App = () => {
const [todos, setTodos] = useState([])
useEffect(() => {
const fetchAllTodos = async () => {
const response = await fetch(URL)
const allTodos = await response.json()
setTodos(allTodos)
}
fetchAllTodos()
}, [])
return (
<ul>
{[...todos]
.filter((todo) => todo.completed)
.map((completedTodo) => (
<li key={completedTodo.id}>
<p>{completedTodo.id}</p>
<a href="#">{completedTodo.title}</a>
</li>
))}
</ul>
)
}
This component has multiple responsibilities, as outlined below:
- Fetching data
- Compiling the fetched data
- Rendering
Let's break it down into smaller components, each with a single responsibility.
import React, { useEffect, useState } from 'react'
const URL = 'https://jsonplaceholder.typicode.com/todos'
// Custom hook
export const useAllTodos = () => {
const [todos, setTodos] = useState([])
useEffect(() => {
const fetchAllTodos = async () => {
const response = await fetch(URL)
const allTodos = await response.json()
setTodos(allTodos)
}
fetchAllTodos()
}, [])
return { todos }
}
// Component
export const App = () => {
const { todos } = useAllTodos()
return (
<ul>
{[...todos]
.filter((todo) => todo.completed)
.map((completedTodo) => (
<li key={completedTodo.id}>
<p>{completedTodo.id}</p>
<a href="#">{completedTodo.title}</a>
</li>
))}
</ul>
)
}
You can also extract the compilation function into a utility function.
// Util function
export const getCompletedTodos = (todos) => todos.filter((todo) => todo.completed)
// Component
export const App = () => {
const { todos } = useAllTodos()
return (
<ul>
{getCompletedTodos(todos).map((completedTodo) => (
<li key={completedTodo.id}>
<p>{completedTodo.id}</p>
<a href="#">{completedTodo.title}</a>
</li>
))}
</ul>
)
}
Lastly, you can extract the To Do list function to the TodoItem.
// TodoItem
export const TodoItem = ({ todo }) => (
<li>
<p>{todo.id}</p>
<a href="#">{todo.title}</a>
</li>
)
export const App: React.FC = () => {
const { todos } = useAllTodos()
return (
<ul>
{getCompletedTodos(todos).map((completedTodo) => (
<TodoItem key={completedTodo.id} todo={completedTodo} />
))}
</ul>
)
}
This achieves the Single Responsibility Principle.
・Fetching data
・Compiling the fetched data
・Rendering
👇
・Fetching data(custom hook)
・Compiling the fetched data(util)
・Rendering(component)
Top comments (0)