・The dependency that imports an extra module should depend on the abstract interface, but not the concrete one.
Because this makes it easy to modify the application, while an application that depends on a concrete interface might collapse immediately.
Here is an example using the swr.
import useSWR from 'swr'
const fetcher = async (url) => {
const res = await fetch(url)
return res.json()
}
export const Todo = () => {
const { data } = useSWR('https://jsonplaceholder.typicode.com/todos', fetcher)
if (!data) return <p>loading....</p>
return (
<ul>
{data.map((todo) => {
return (
<li>
<span>{todo.id}</span>
<span>{todo.title}</span>
</li>
);
})}
</ul>
)
}
The snippet above has several issues.
・Fetches data within the Todo component.
・The Todo component depends on the concrete interface.
Let's consider if we convert the swr to the react-query that provides superior functionality than swr. Can we do it easily?
Here are several issues.
・Variety of components depends on the swr directly. We are bound to replace it in every component.
・If each component has its own different errors, we have to fix them.
And other issues exist in the application.
Let's deal with the issue by applying the DPI to direct the dependency to the interface.
import useSWR from 'swr'
interface IUseFetch<T> {
key: string
fetcher: () => Promise<T>
}
interface IResponse<T> {
data: T | undefined,
error: string | undefined
isValidating: boolean
}
export const useFetch = <T>({ key, fetcher }: IUseFetch<T>): IResponse<T> => {
const { data, error, isValidating } = useSWR<T, string>(key, fetcher)
return {
data,
error,
isValidating
}
}
import { useFetch } from './useFetch'
type ResponseType = {
id: number
title: string
}
const fetcher = async (): Promise<ResponseType[]> => {
const url = 'https://jsonplaceholder.typicode.com/todos'
const res = await fetch(url)
return res.json()
}
export const Todo = () => {
const { data } = useFetch<ResponseType[]>({ key: '/todos', fetcher })
if (!data) return <p>loading....</p>
return (
<ul>
{data.map((todo) => {
return (
<li>
<span>{todo.id}</span>
<span>{todo.title}</span>
</li>
);
})}
</ul>
)
}
Above codes, we defined useFetch hook to wrap the swr, and call it from the Todo component.
In this case, we have only to modify the useFetch hook if we apply the react-query in the application.
Top comments (0)