Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
333 views
in Technique[技术] by (71.8m points)

reactjs - How to fetch data in React blog app and stay DRY?

The question is simple. How to fetch data in your React blog and stay DRY? Let's say that you have just two components in your blog - PostsList and SinglePost, in both components you must fetch data, activate isLoading state, etc. There will be chunks of the same code in both components.

I investigated the situation a little bit, checking React-blog demo apps of big headless CMS providers, like Prismic or Sanity.io, and they all just repeat fetch functions in both PostsList and SinglePost.

Does anybody have any idea? You can point me to some good resources?

question from:https://stackoverflow.com/questions/65908657/how-to-fetch-data-in-react-blog-app-and-stay-dry

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can achieve this by using High Order Components. You can use them for reusing component logic. Let me show you an example of how to handle the isLoading with a HOC:

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

As you can see this HOC is receiving the WrappedComponent and a message that you can set depending on your component. Then you will have to wrap every component where you want to show the loading feedback with the HOC and you can use the setLoading prop to stop showing the loading feedback:

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

This way you avoid repeating this process for every component. Regarding the data fetching you can create a Hook or a function that receives dynamic params so you can just call something like fetchData(url). Here is an example of a dynamic function for making request using 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
  }
 }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...