首页 > 解决方案 > 如何为使用 React 钩子的 Apollo 查询创建包装器

问题描述

要使用 Apollo 执行查询,您可以使用render props方式或hooks方式。

https://www.apollographql.com/docs/react/data/queries/

取决于您使用的是类组件还是功能组件。

在这些示例中,您必须处理加载和错误状态,例如,

const { loading, error, data } = useQuery(GET_DOGS);

if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;

感觉过了一段时间,每次我想查询时都会重复。所以,我想为它做一个包装。

因此,我找到了一篇关于如何以组件方式执行此操作的帖子:https ://medium.com/naresh-bhatia/graphql-concepts-i-wish-someone-explained-to-me-a-year-ago- 959b234ff430

但是,找不到功能方式的答案。

我尝试了一个解决方案,它有效,但我不知道它是否是一个好的解决方案。

因此,我制作了一个 React 功能组件,它应该进行加载和错误处理,然后返回数据。

export function GraphQLRequest({ requestFunction, params, handleData }) {
    if (typeof requestFunction !== 'function') {
        return <ErrorAlert message={'Request function is not a function'} />
    }

    const { loading, error, data } = requestFunction(...params)

    if (loading) {
        return <div>Loading...</div> // TODO; loading spinner
    }
    if (error) {
        return <ErrorAlert message={error.message} />
    }

    handleData(data)
    return <div></div>
}

从另一个组件中,我可以将我的GraphQLRequest组件放入渲染部分:

export function SomeView({ match: { params } }) {
    const [data, setData] = useState(null)

    const id = params.someId

    return (<div>
        <p className='title'>SomeItem {id}</p>
        <GraphQLRequest 
            handleData={data => setData(data)}
            requestFunction={getSomeInfoFromId}
            params={[id]}
        />
    </div>)
}

它工作正常。但是我觉得有一个空组件只是用来获取数据有点不确定。我感觉不确定是对的吗?还是我应该继续?

标签: javascriptreactjsgraphqlapollo

解决方案


您可以使用HOC。它与 Appollo 客户端 3 和useQuery Hook配合得很好

export const withQuery = (WrappedComponent, query) => {
  return (props) => {
    const { loading, error, data } = useQuery(query);

    if (loading) {
      return <div>Loading</div>;
    } else if (error) {
      return <div>Error</div>;
    }
    return (<WrappedComponent data={data} {...props} />)
  };
}

用法:

const MyFunctionalComponent = ({ data }) => {
   // do something with data
};

export default withQuery(MyFunctionalComponent, myQuery);

推荐阅读