解构获取的数据反应

Destructurize fetched data react

上下文

我的所有组件都需要获取数据。

我如何获取

因此我使用自定义挂钩,它使用 useEffect 挂钩和 axios 获取数据。挂钩 returns data 或加载或错误 falsedata 是一个主要包含对象数组的对象。

我是如何渲染的

我使用三元 (?) 或使用短路 (&&) 运算符以条件方式呈现我的数据。

问题

如果我的 useFetch 钩子 returning falsedata 以我可以重用逻辑或最小化的方式,我如何解构我的数据依赖接收组件的实现?

我试过的

//issue
fuction Receiver() {
    const query = headerQuery();
    const data = useFetch(query);
    const loaded = data.data //either ```false``` or object with ```data```
/*
The following part should be in an easy condition or passed to an combined logic but I just dont get it
destructuring assignment varies from component to component

ex:
    const {
        site,
        data: {
            subMenu: {
                description,
                article_galleries,
                image: {
                    caption,
                    image: [{url}],
                },
            },
        },
    } = data;
*/
return loaded?(
    <RichLink
        title={title}
        text={teaserForText}
        link={link}
        key={id}
    ></RichLink>):<Loading />

(

//for context
import axios from "axios";
import {
  useHistory
} from "react-router-dom";
import {
  useEffect,
  useState
} from "react";

function useFetch(query) {
  const [data, setData] = useState(false);
  const [site, setSite] = useState(""); // = title
  const history = useHistory();

  useEffect(() => {
    axios({
        url: "http://localhost:1337/graphql",
        method: "post",
        data: {
          query: query,
        },
      })
      .then((res) => {
        const result = res.data.data;
        setData(result);

        if (result === null) {
          history.push("/Error404");
        }
        setSite(Object.keys(result)[0]);
      })
      .catch((error) => {
        console.log(error, "error");
        history.push("/Error");
      });
  }, [query, history, setData, setSite]);


  return {
    data: data,
    site: site
  };
}

export default useFetch;

)

您可以 return 从挂钩中获取错误、数据和加载状态。然后实现挂钩的组件可以解构所有这些并根据结果做一些事情。示例:

const useAsync = () => {
 // I prefer status to be idle, pending, resolved and rejected.
 // where pending status is loading.
  const [status, setStatus] = useState('idle')
  const [data, setData] = useState([])
  const [error, setError] = useState(null)
  
  useEffect(() => {
   setStatus('pending')

   axios.get('/').then(resp => {
     setStatus('resolved')
     setData(resp.data)
   }).catch(err => {
     setStatus('rejected') // you can handle error boundary
     setError(err)
   })
  }, []}

 return {status, data, error}
}

实现这个钩子的组件

const App = () => {
  const {data, status, error} = useAsync()
  
  if(status === 'idle'){
    // do something
  }else if(status === 'pending'){
    return <Loader />
  }else if(status === 'resolved'){
    return <YourComponent data ={data} />
  }else{
    return <div role='alert'>something went wrong {error.message}</div>
  } 


}

使用动态 api 函数可以进一步增强挂钩。