React Umi SSR SSG 使用TypeScript的最佳实践

说明

Umi文档对TypeScript 只字未提 (太糟糕了, 感觉像是 KPI 项目),
所以只能自己看源码 和 Github 去捞TS的定义
最终封装为一个类型IUmiPage

使用的时候只需要指定 两个泛型 ( 路由参数类型 与 getInitialProps 返回值 )
不指定,则默认{ }空对象

版本

"umi": "^3.5.21"

代码

核心type

不开启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>;
};

[id].tsx

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;

.umirc.ts

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']);
    },
  },
});

index.tsx

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>
  );
}


目录

React Umi SSR SSG 使用TypeScript的最佳实践_第1张图片

你可能感兴趣的:(JavaScript,react.js,typescript,umi,SSG,SSR)