【问题标题】:Disable prefetch on SWR在 SWR 上禁用预取
【发布时间】:2021-02-07 00:58:17
【问题描述】:

我正在尝试为我的数据获取实现 swr 库。我曾经使用普通的 axios 和我创建的一些自定义钩子。 我遇到的问题是,由于某种原因,swr 在设置默认 axios 标头之前触发了 get 请求,因此在发送标识我的应用程序帐户所需的标头时丢失了。 我的猜测是它与 SWR 的预取功能有关,但这只是一个疯狂的猜测,不知道如何防止这种情况发生。

import axios from "axios";
import React, {useLayoutEffect} from "react";
import useSWR from "swr";


function Child({match}) {
    const fetcher = () => {
        console.log('Should happen second')
        axios.get('https://api.mydomain.com').then(res => res.data)
    }

    const {data} = useSWR('/account/specific/data', fetcher)

    return <div>{JSON.stringify(data)}</div>
}

export default function Account({match}) {

    let accountId = match.params.accountId;

    useLayoutEffect(() => {
        console.log('Should happen first')
        axios.defaults.headers.common["Account-Token"] = accountId;
    }, [accountId]);

    return <Child/>
}

【问题讨论】:

    标签: reactjs axios vercel swr


    【解决方案1】:

    您正在使用没有 asyncawait 的 axios,而且您在方法获取器中没有 return,请更改此方法下一个方法:

        const fetcher = async () => {
            return await axios.get('https://api.mydomain.com').then(res => res.data)
        }
    

    【讨论】:

      【解决方案2】:

      我能够解决将 initialData 添加到 useSWR 挂钩选项的问题。

          const { data, error } = useSWR('/api/data', fetcher, initialData: [], revalidateOnMount: true)
      

      【讨论】:

        【解决方案3】:

        你的序列错了。

        1) 如果您的组件尚未准备好生成,您可能应该返回 null。

        export default function Account({match}) {
        
            let accountId = match.params.accountId;
        
            useLayoutEffect(() => {
                console.log('Should happen first')
                axios.defaults.headers.common["Account-Token"] = accountId;
            }, [accountId]);
            
            if (!accountId) return null  //<-- don't generate the Child component until you are ready.
        
            return <Child/>
        }
        

        2) 如果你真的想在 mount 时禁用 SWR fetch,那就设置 { revalidaOnMount: false }

        例如

        const {data} = useSWR('/account/specific/data', fetcher, { revalidateOnMount: false})
        

        3) 或者您可以使用条件提取,以便仅在您的变量准备好时提取。

        const { data } = useSWR( accountID ? /url/path : null, fetcher )
        

        当key为null时useSWR钩子不会调用fetcher。

        【讨论】:

        • 感谢您的回答。选项 1 和 2 不起作用。选项 3 我没有尝试,因为在调用 useSWR 时我没有可用的 accountId。我在默认 axios 标头中设置此值是有原因的,那就是避免通过代码发送到所有数据获取操作。设置 initialData 和 revalidateOnMount: true 确实有效
        • 另外,accountID 在第一次渲染时就准备好了,因为它取自路由参数并且不依赖于任何异步操作。
        猜你喜欢
        • 2019-06-28
        • 1970-01-01
        • 1970-01-01
        • 2021-04-05
        • 2014-07-04
        • 2021-09-28
        • 2023-02-04
        • 2021-06-30
        • 2021-02-10
        相关资源
        最近更新 更多