一、升级步骤
1、本地node建议升级到v20(next@13要求node@18,react@18、react-dom@18、chakra-ui@2)
2、支持渐进式升级next13,升级的项目需按 next 官方添加环境变量NEXT_PUBLIC_NEXT13,请devops帮忙Dockerfile构建时添加.env 文件到 pod中
3、由于升级 next13,公共组件客户端需要区分nginx与next,nginx项目需要按 create-react-app 官方添加环境变量REACT_APP_IS_NGINX=true
,不用改Dockerfile
4、由于历史原因,@chakra-ui/theme-tools会升级失败,需要在resolutions指定为新版本"@chakra-ui/theme-tools": "2.1.2"
5、yarn add [email protected] [email protected] [email protected] @chakra-ui/[email protected] @emotion/[email protected] @emotion/[email protected] @emotion/[email protected] @emotion/[email protected] [email protected]
6、升级eslint插件 yarn add -D [email protected]
7、mik-ssr-web、mik-ssr-dc、mik-ssr-auth已上 prod环境,需要全量测试,升级后包增加100kb后期解决
8、next官方升级文档Upgrading: App Router Migration
二、调试方法
yarn start启动本地调试,通过组件栈与调试面板有助于查找报错原因
三、常见业务报错
1、next@13对react-router-dom兼容性不好,可能产生白屏。建议删除react-router-dom,使用next/router、next/link等。如需兼容nginx项目,统一使用useMikRouter
与MikLink
,智能判断next/link、react-router-dom的Link、chakra-ui的Link
import { useMikRouter, MikLink } from 'michaels-ssr/hooks/nextOrNginx'; export default function Component() { const router = useMikRouter(); // 内部判断next或者nginx,添加react-router-dom的useLocation属性 router.push('/'); console.log('pathname', router.pathname) return <MikLink href='/home' p="30px" bg='tomato'>Home</MikLink> //支持chakra-ui样式 }
2、当useEffect的回调函数是异步函数时,可能产生白屏。async函数隐式返回一个Promise对象,React18框架错误地将其解释为返回的清理函数,这会在组件因导航而卸载时导致错误。
应该用函数包裹一层,需保留{},useEffect(() => { getIpFn() }, [])
错误写法: useEffect(async () => { const ipText = await fetch(`${env.COMMERCE_API}/shipping/getRequestIp`); }, []);
正确写法: const getIpFn = async () => { const ipText = await fetch(`${env.COMMERCE_API}/shipping/getRequestIp`); } useEffect(() => { getIpFn() }, []); //应该用函数包裹一层,需保留{}
2、next13的next/link的href属性,仅支持 string 与 object,undefined会报如下错误
4、水合一致性报错,react18水合检验更严格,会报418、423、425错误
函数组件的typeof window !== 'undefined'
应改为自定义 hook
import useIsClient from 'michaels-ssr/hooks/useIsClient'; export default function Component() { const isClient = useIsClient(); return isClient ? 'Is Client' : 'Is Server' }
5、useMediaQuery当客户端屏幕宽度与服务端渲染不一致报418、423,建议服务端渲染默认1440
const [is1440] = useMediaQuery(`(max-width: 1439px)`); const [is1024] = useMediaQuery(`(max-width: 1023px)`);
6、a 标签不能嵌套 a标签
7、其他水合一致性报错详见:
next官方文档Text content does not match server-rendered HTML
或 react官方文档hydrateRoot – React
8、ping接口使用正确es6写法
const ping = require('michaels-ssr/pages/api/ping'); module.exports = ping;
改为
import ping from 'michaels-ssr/pages/api/ping' export default ping
9、Toast 不弹出
过渡解决方案 在当前页使用standalone toast 参考,同时要保证theme color 值正确可用 Upgrading to v2
_app.jsx example:
import { createStandaloneToast } from '@chakra-ui/toast'
import { withCustomer } from 'michaels-ssr/pages/_appWithOutHeaderFooter';
import CommonLayout from 'michaels-ssr/components/Layout';
const { ToastContainer } = createStandaloneToast()
function CustomeLayout(props) {
return (
<>
<ToastContainer />
<CommonLayout {...props} />;
</>
);
}
export default withCustomer({
newApp: true,
Layout: CustomeLayout,
});
标签:13,const,18,ssr,react,ui,chakra,next
From: https://www.cnblogs.com/jerry-mengjie/p/18165041