NextJs14遇到的问题

2024/4/21 21:31:47
React ,NextJs

useEffect调用两次


import {useEffect} from "react";

const App = {} =>{
    useEffect(()=>{
        console.log('挂载完成执行')
        return () => {
            console.log('卸载时执行')
        }
    },[])
}

在开发模式,严格模式中,上述代码表现为

挂载完成执行
卸载时执行
挂载完成执行
卸载时执行

目的是为了模拟立即卸载和重新挂在组件。在生产环境中无影响。


服务端渲染

之前相关API为getServerSideProps,以及另一个页面静态化APIgetStaticProps。在14的App Router模式下已经不再使用。 取而代之的是使用以及配置fetch

//...


const App = async () =>{
    const staticData = await fetch('https://...') // 在build 阶段将会执行一次,随后再访问页面不会再请求
    const servserSideData =  await fetch('https://...', { cache: "no-store"}) // 每次访问页面时,都会在服务端进行一次请求获取最新的数据
}

在实际操作中有遇到PATCH请求必须大写,否则将报错400 Bad Request。 而getpost请求会自动转成大写。


代理配置

看文档是说在根目录下的next.config.mjs里配置


/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://api.example.com/:path*'
      }
    ]
  },
};

export default nextConfig;

但在实际开发中有遇到服务端的请求并没有走next.config.mjs里配置的代理,目前的解决方法是在封装fetch方法时,判断是否在服务端,如果在服务端则进行链接替换。

const Proxy: any = {
    "/api": {
        target: "http://api.example.com"
    },
};


const customFetch = async (url: string, options: RequestInit = {}) => {

// ...
    let fullUrl = `${url}`;
    if (typeof window === "undefined") {
        for (let i = 0; i < Keys.length; i++) {
            const key = Keys[i];
            if (fullUrl?.startsWith(key)) {
                const url = fullUrl?.replace(key, Proxy[key].target);
                fullUrl = url;
                break;
            }
        }
    }
// ...

}