如何在 React 博客应用程序中获取数据并保持 DRY?
How to fetch data in React blog app and stay DRY?
问题很简单。如何在你的 React 博客中获取数据并保持 DRY?假设您的博客中只有两个组件 - PostsList 和 SinglePost,在这两个组件中您都必须获取数据,激活 isLoading 状态等。两个组件中会有相同的代码块。
我稍微调查了一下情况,查看了 Prismic 或 Sanity.io 等大型无头 CMS 提供商的 React-blog 演示应用程序,它们都只是在 PostsList 和 SinglePost 中重复获取功能。
有人知道吗?你能给我指点一些好的资源吗?
您可以使用 High Order Components 来实现。您可以使用它们来重用组件逻辑。让我向您展示一个如何使用 HOC 处理 isLoading 的示例:
HOC:
import React, { useState } from 'react'
const hocLoading = (WrappedComponent, loadingMessage) => {
return props => {
const [ loading, setLoading ] = useState(true)
const setLoadingState = isComponentLoading => {
setLoading(isComponentLoading)
}
return(
<>
{loading && <p>{loadingMessage}</p>} //message showed when loading
<WrappedComponent {...props} setLoading={setLoadingState} />
</>
)
}
}
export default hocLoading
如您所见,此 HOC 正在接收 WrappedComponent 和一条消息,您可以根据您的组件进行设置。然后你将不得不用 HOC 包装你想要显示加载反馈的每个组件,你可以使用 setLoading 属性停止显示加载反馈:
const Component = props => {
const { setLoading } = props
useEffect(() => {
const loadUsers = async () => {
await fetchData() // fetching data
setLoading(false) // this function comes from the HOC to set loading false
}
loadUsers()
},[ ])
return (
<div className="App">
{usuarios.data.map(x => <p key={x.id}>{x.title}</p>)}
</div>
);
}
export default hocLoading(Component, "Data is loading") //component wrapped
// with the HOC and setting feedback message
这样您就可以避免对每个组件重复此过程。关于数据获取,您可以创建一个 Hook 或一个接收动态参数的函数,这样您就可以调用 fetchData(url) 之类的东西。这是使用 axios 发出请求的动态函数的示例:
const baseUrl = "" //your BASE URL
async function request(url,method,data){
try {
const response = await axios({
method,
url: `${baseUrl}${url}`,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
data: data ? data : undefined
})
return response
} catch (e) {
// handle error
}
}
问题很简单。如何在你的 React 博客中获取数据并保持 DRY?假设您的博客中只有两个组件 - PostsList 和 SinglePost,在这两个组件中您都必须获取数据,激活 isLoading 状态等。两个组件中会有相同的代码块。
我稍微调查了一下情况,查看了 Prismic 或 Sanity.io 等大型无头 CMS 提供商的 React-blog 演示应用程序,它们都只是在 PostsList 和 SinglePost 中重复获取功能。
有人知道吗?你能给我指点一些好的资源吗?
您可以使用 High Order Components 来实现。您可以使用它们来重用组件逻辑。让我向您展示一个如何使用 HOC 处理 isLoading 的示例:
HOC:
import React, { useState } from 'react'
const hocLoading = (WrappedComponent, loadingMessage) => {
return props => {
const [ loading, setLoading ] = useState(true)
const setLoadingState = isComponentLoading => {
setLoading(isComponentLoading)
}
return(
<>
{loading && <p>{loadingMessage}</p>} //message showed when loading
<WrappedComponent {...props} setLoading={setLoadingState} />
</>
)
}
}
export default hocLoading
如您所见,此 HOC 正在接收 WrappedComponent 和一条消息,您可以根据您的组件进行设置。然后你将不得不用 HOC 包装你想要显示加载反馈的每个组件,你可以使用 setLoading 属性停止显示加载反馈:
const Component = props => {
const { setLoading } = props
useEffect(() => {
const loadUsers = async () => {
await fetchData() // fetching data
setLoading(false) // this function comes from the HOC to set loading false
}
loadUsers()
},[ ])
return (
<div className="App">
{usuarios.data.map(x => <p key={x.id}>{x.title}</p>)}
</div>
);
}
export default hocLoading(Component, "Data is loading") //component wrapped
// with the HOC and setting feedback message
这样您就可以避免对每个组件重复此过程。关于数据获取,您可以创建一个 Hook 或一个接收动态参数的函数,这样您就可以调用 fetchData(url) 之类的东西。这是使用 axios 发出请求的动态函数的示例:
const baseUrl = "" //your BASE URL
async function request(url,method,data){
try {
const response = await axios({
method,
url: `${baseUrl}${url}`,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
data: data ? data : undefined
})
return response
} catch (e) {
// handle error
}
}