Umi文档对TypeScript 只字未提 (太糟糕了, 感觉像是 KPI 项目),
所以只能自己看源码 和 Github 去捞TS的定义
最终封装为一个类型IUmiPage
使用的时候只需要指定 两个泛型 ( 路由参数类型 与 getInitialProps 返回值 )
不指定,则默认{ }
空对象
"umi": "^3.5.21"
不开启SSR SSG ,
IGetInitialProps
会找不到, 所以加上@ts-ignore
//@ts-ignore
import { IGetInitialProps, IRouteComponentProps } from 'umi';
/**
* 将 umi 的类型,封装成一个type .
* 泛型1 是 路由中的参数类型,
* 泛型2 是 getInitialProps返回的类型, 最终会注入到组件的props中
*/
type IUmiPage<TRouteProps = {}, TInitResultProps = {}> = FC<
IRouteComponentProps<TRouteProps> & TInitResultProps
> & {
getInitialProps?: IGetInitialProps<TInitResultProps, TRouteProps>;
};
import { FC, memo, useEffect, useState } from 'react';
//@ts-ignore
import { IGetInitialProps, IRouteComponentProps } from 'umi';
/**
* 将 umi 的类型,封装成一个type .
* 泛型1 是 路由中的参数类型,
* 泛型2 是 getInitialProps返回的类型, 最终会注入到组件的props中
*/
type IUmiPage<TRouteProps = {}, TInitResultProps = {}> = FC<
IRouteComponentProps<TRouteProps> & TInitResultProps
> & {
getInitialProps?: IGetInitialProps<TInitResultProps, TRouteProps>;
};
//----组件------
let Post: IUmiPage<{ id: string }, { myData: string }> = (props) => {
const [date, setDate] = useState<string>('');
useEffect(() => {
setDate(new Date().toLocaleString());
}, []);
return (
<>
<h3>拿到 getInitialProps 返回的属性 : {props.myData}</h3>
<h3>拿到路由中的属性 : {props.match.params.id}</h3>
<h3>显示useEffect中的属性 : {date}</h3>
</>
);
};
//只能先使用 memo,再添加静态属性和方法,否则 umi获取不到 静态属性和方法, 就失效了
Post = memo(Post);
Post.getInitialProps = async (props) => {
console.log('我是 getInitialProps: ', props.match.params.id);
return Promise.resolve({
myData: '我是数据',
});
};
// 最后不要使用memo,umi会获取不到附加的静态属性和方法, 只能提前加 ↑ .
export default Post;
Umi 的配置文件
import { defineConfig } from 'umi';
export default defineConfig({
nodeModulesTransform: {
type: 'none',
},
// 路由
routes: [
{ path: '/', component: '@/pages/index' },
{ path: '/post/:id', component: '@/pages/post/[id]' },
{ path: '/user', component: '@/pages/user' },
],
fastRefresh: {},
// 开启 SSR 与 SSG
ssr:{},
exportStatic: {
// 指定预渲染的路由
extraRoutePaths: async () => {
// const result = await request('https://your-api/news/list');
// 此处故意不写 "/post/3"
return Promise.resolve(['/post/1', '/post/2']);
},
},
});
extraRoutePaths 中未指定的带参数的页面,
不会生成HTML,所以无法通过手动输入地址进入(或者刷新)
涉及到 hash 和 history 路由模式, 还有 nginx 和后端配置, 具体自己查吧.
https://github.com/umijs/umi/issues/186
import { Link } from 'umi';
export default function IndexPage() {
return (
<div>
<h3><Link to="/post/1">post 1</Link></h3>
<h3><Link to="/post/2">post 2</Link></h3>
<h3><Link to="/post/3">post 3</Link></h3>
</div>
);
}