美文网首页
759.【前端】graphql 数据接入优化案例

759.【前端】graphql 数据接入优化案例

作者: 七镜 | 来源:发表于2023-08-11 16:39 被阅读0次

一、案例背景

七镜在基于react编写页面时,发现一段每个页面都重复的graphql相关代码,代码如下:

// 标记1
    const [dataNews, setDataNews] = useState<TGqlDimensionNews>({
        code: 0, content: [], count: 0, msg: {fail: "", success: ""}
    })
// 标记2
    const [condNews, setCondNews] = useState<TCondType>({
        page_after: 0,
        page_size: 10,
        order_by: "created_at",
        sort_by: "desc",
        detail: {},
        keyword: {
        },
        table_name: "dimension_news",
    })
// 标记3
    //useGraphql
    const [getDimensionNews, {data: dataDimensionNews, error}] = useLazyQuery(QUERY_DIMENSION_NEWS)
// 标记4
    // useEffect:
    useEffect(() => {

        getDimensionNews({
            variables: {
                from_id: auth.data.base.id,
                from_nickname: auth.data.account,
                content: JSON.stringify(condNews)
            }
        })
            .then(resp => {

                let tmpData = {...resp.data.dimensionNews} as TGqlDimensionNews
                // console.log("result:", tmpData.content[0].base_dimension.content)
                if (tmpData.code === 200) {
                    setDataNews(tmpData)

                }
            })
            .catch(e => {
                console.log(e)
            })
    }, [condNews])
  • 标记1:定义服务端数据接收过来的结构体
  • 标记2:定义服务端数据获取的过滤条件
  • 标记3:定义graphql数据获取的函数入口
  • 标记4:通过graphql数据获取函数接收服务端数据,并存入保存页面数据的地方(dataNews)

我们知道,写代码的时候,面对第一个新需求,快速实现一段代码;面对第二个差不多的需求,针对刚刚那段代码,复制粘贴并做一些小小的修改;面对第三个差不多的需求,应当重构前面的代码。

二、优化方案

首先,技术实现肯定是基于 react hooks。详细代码如下:

import React, {useState, useEffect, useContext} from "react";
import {DocumentNode, useLazyQuery} from "@apollo/react-hooks";
import {
    TCondType,
    TResponseCommon
} from "../../register-center/graphql/graphql-types/graphql-types";
import {ContextAuth} from "../../register-center/context/auth/context-auth";


export interface useGraphqlGetProps {
    cond: TCondType, // 接口参数
    gql_schema_query: DocumentNode, // Graphql schema
    gql_data_query_name: string, // 查询的表名
    setData: React.Dispatch<React.SetStateAction<TResponseCommon>> // 设置查询结果
}

function useGraphqlQuery(props: useGraphqlGetProps): [TCondType, React.Dispatch<React.SetStateAction<TCondType>>] {
    const [auth, setAuth] = useContext(ContextAuth) // 接口参数中的用户名和用户昵称的来源
    const [cond, setCond] = useState<TCondType>(props.cond)
    //useGraphql
    const [getData, {error}] = useLazyQuery(props.gql_schema_query)
    // useEffect
    useEffect(() => {
        if (!cond.table_name) {
            console.error("please replace cond.table_name")
            return
        }
        getData({
            variables: {
                from_id: auth.data.base.id,
                from_nickname: auth.data.account,
                content: JSON.stringify(cond)
            }
        })
            .then(resp => {

                let tmpData = {...resp.data[props.gql_data_query_name]}
                // console.log("result:", tmpData.content[0].base_dimension.content)
                if (tmpData.code === 200) {
                    props.setData(tmpData)
                }
            })
            .catch(e => {
                console.error(e)
            })
    }, [cond])
    return [cond, setCond]
}

export default useGraphqlQuery

实现思路:

  1. 该hook的初始化依赖于传入的【接口参数】、【graphql schema】、【查询的表名】、【设置查询结果的函数】
  2. 该hook中的实现逻辑与之前代码一致。
  3. 替换之前的代码中与传入参数一致的地方。

三、优化结果

优化后计入数据的代码:

    const [data, setData] = useState<TGqlDimensionApplicationCase>(initResponseCommon)

    const [cond, setCond] = useGraphqlQuery({
        cond: {
            ...initCond,
            table_name: "dimension_application_case",
        },
        gql_schema_query: QUERY_DIMENSION_APPLICATION_CASE,
        gql_data_query_name: "dimensionApplicationCase",
        setData: setData
    })

  • 从优化前后的代码行数,可以看到代码量已经大大减少了,封装完毕。

相关文章

网友评论

      本文标题:759.【前端】graphql 数据接入优化案例

      本文链接:https://www.haomeiwen.com/subject/oksapdtx.html