关于 next.js 13 请求封装的最佳实践的疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Outshine
V2EX    Next.js

关于 next.js 13 请求封装的最佳实践的疑问

  •  
  •   Outshine 2023-04-10 02:16:29 +08:00 5398 次点击
    这是一个创建于 916 天前的主题,其中的信息可能已经有所发展或是发生改变。
    首先声明,本人之前一直做的都是 SPA 项目,直接用 `axios` 之类的封装一次即可,而我说的封装是指类似做 baseUrl 、统一错误处理、统一设置请求 headers 等

    ---

    我看 next.js 13 官方建议 `Server Component` 使用 `fetch`,`Client Component` 请求数据使用 `swr` 或者 `react query`

    而 `swr` 官方文档和网上文章没有关于 `swr` 提交数据相关的(看起来就是专门获取数据的库?)

    那么,务端组件请求、客户端组件请求、客户端提交数据是要封装三次嘛?想问下各位 next.js 前辈有什么好一点的实践嘛?
    8 条回复    2023-04-10 19:26:25 +08:00
    seki
        1
    seki  
       2023-04-10 02:34:23 +08:00
    swr 有的,叫做 mutation ,按字找一下

    server 和 client 行的境本不一,分封一下比合理。client 的,swr 可以全局配置 fetcher 和 mutator ,取於你的目,也可以抽象 get / post 方法再封
    himself65
        2
    himself65  
       2023-04-10 02:38:21 +08:00 via iPhone   2
    swr 是一个网络无关的异步数据获取库,你可以拿来跑任何异步函数。
    在你说的这个例子里面,你可以在顶层写一个 fetcher(key),包装了 fetch api ,然后三个部分都可以间接 /直接调用这个 API
    shuding
        3
    shuding  
       2023-04-10 05:21:05 +08:00   1
    `useSWRMutation` 这个 hook 可以用来处理 POST/PUT/DELETE 之类的请求:

    https://swr.vercel.app/docs/mutation#useswrmutation
    B3C933r4qRb1HyrL
        4
    B3C933r4qRb1HyrL  
       2023-04-10 08:35:47 +08:00 via Android
    握草,上面两位大佬亲自回复
    wu67
        5
    wu67  
       2023-04-10 08:44:59 +08:00
    最近也在看, 我也是搞不懂, getServerSideProps 里面貌似只有 fetch, 这玩意根本没有文档, 怎么发 post 请求都不明白...

    还是说 swr 也能在服务端代码运行的?

    还有 swr 如果在不停的刷新新数据, 那不是一直在调 API 读数据库? 用户量上来之后这不是平白增加数据库压力嘛?
    iliaoliao
        6
    iliaoliao  
       2023-04-10 11:30:30 +08:00
    首先你需要明白哪些请求是幂等的,增删改查中查是幂等的所以使用 `useQuery` 这类带有数据缓存的 hook 是最合适的,而增删改等非幂等操作则使用带有突变操作的 hook `useMutation`。
    我推荐 react-query 和我开源的 react-query-kit 结合使用。可以做到在 getServerSideProps 和组件中的写法是一致的,几乎没有什么心智负担,顺便把写法贴在下面

    ```js
    import { createQuery } from 'react-query-kit'

    const usePost = createQuery({
    primaryKey: '/posts',
    queryFn: ({ queryKey: [primaryKey, variables] }) => {
    // primaryKey equals to '/posts'
    return fetch(`${primaryKey}/${variables.id}`).then(res => res.json())br /> },
    })

    const variables = { id: 1 }

    export default function Page() {
    const { data } = usePost({ variables, suspense: true })

    return (
    <div>
    <div>{data?.title}</div>
    <div>{data?.content}</div>
    </div>
    )
    }

    // nextjs example
    export async function getStaticProps() {
    const queryClient = new QueryClient()

    await queryClient.prefetchQuery({
    queryKey: usePost.getKey(variables),
    queryFn: usePost.queryFn
    })

    return {
    props: {
    dehydratedState: dehydrate(queryClient),
    },
    }
    }
    ```
    Outshine
        7
    Outshine  
    OP
       2023-04-10 17:56:52 +08:00
    感谢各位大佬的解答

    @himself65 #2 因为 next.js 13 规定客户端组件必须在文件头增加 'use client' ,而且 swr 使用了客户端组件才能用的一些 hooks ,所以服务端组件和客户端组件貌似还是需要单独封装

    @shuding #3 瞅了瞅这个文档,文档里的 demo 是将 token 手动传入,貌似不够优雅。但如果统一封装,又会遇到上面的问题(因为服务端和客户端获取 token 的途径肯定不一样的,我尝试过通过判断是否服务端来从不同路径获取,但是 next.js 13 不允许服务端组件里存在客户端的代码,连导入都不行)

    @wu67 #5 fetch 发 post 请求倒是很简单,直接 fetch('url', { method: 'POST' } 即可。swr 在 next.js 13 上并不能在服务端运行(我没试过之前的版本)

    @iliaoliao #6 感谢,您这个看起来也不支持 next.js 13 呢?而且我按照您 github 的文档并没有顺利跑起来。
    iliaoliao
        8
    iliaoliao  
       2023-04-10 19:26:25 +08:00
    @Outshine
    GitHub 文档上都有示例项目的,例如这个 nextjs13 的 https://codesandbox.io/s/example-react-query-kit-nextjs-uldl88
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2713 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 07:41 PVG 15:41 LAX 00:41 JFK 03:41
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86