1、初始安装react+ts
npx create-react-app my-app
npx create-react-app react-ts --template typescript 安装为ts
2、安装好react 后面加上ts
2.1 tsc --init 生产tsconfig.js
2.2 引入ts yarn add typescript yarn add @types/react @types/react-dom
2.3 react 里面的文件.js 需要修改为.tsx 包含jsx的都需要改为tsx
3、react 里面的文件.js 需要修改为.tsx
4、安装mobx
yarn add mobx mobx-react-lite
---React Developer Tools安装
---1 下载包 https://www.crx4chrome.com/crx/3068/ 下载crx包
---2 将报的后缀名修改为rar或者zip
---3 解压完成后如下
---4打包完成后在chrome加载已解压的文件
----5加载的文件夹不能删除 删除了插件就找不到了 可以放在一个地方
5、类型断言
//封装userinfo 存到localstorage const Key = "userInfo" //set const setUserInfo = (userInfo)=> { return window.localStorage.setItem(Key, userInfo) } // get const getUserInfo = ():string|null=> { return window.localStorage.getItem(Key) } //remove const removeUserInfo = ()=> { return window.localStorage.removeItem(Key) } export {setUserInfo, getUserInfo, removeUserInfo}
保存的时候
let userInfo = {
token: resp.data.token,
sessionId: resp.sessionId,
username: enterpriseAccount,
relateEnterpriseName: resp.userInfo.enterpriseName,
relateEnterpriseId: resp.userInfo.id,
isSuperAdmin: resp.userInfo.isSuperAdmin,
};
setUserInfo(JSON.stringify(userInfo));
7、组件鉴权 没有token信息就跳转到login
AuthComponent.tsx
//判断用户信息token是否存在 //存在直接渲染 //不存在直接跳转 //AuthComponent 里面加入需要鉴权的组件 import { getUserInfo } from "@/utils/index" import { Navigate } from "react-router-dom" function AuthComponent({ children }) { const userInfo = JSON.parse(getUserInfo() as string); let token = userInfo ? userInfo.token : ''; if (token !=="") { return <>{children}</> } else { //跳转到登录页 return <Navigate to={"/login"} /> } } export { AuthComponent }
使用
/*路有需要鉴权的地方使用*/ <Route path="/" element={ <AuthComponent><Layout /></AuthComponent> }></Route>
8、ts 设置router index 跳转首页
<Route index element={ <AuthComponent><Home /></AuthComponent> }></Route>
9、错误信息
Do you need to change your target library? Try changing the 'lib' compiler option to 'es2021' or later.
"compilerOptions": { "target": "es5" /**指定ECMAScript目标版本**/, "module": "commonjs" /**指定生成哪个模块系统代码**/, "allowJs": true /**允许编译js文件**/, "jsx": "preserve" /**支持JSX**/, "outDir": "build" /**编译输出目录**/, "strict": true /**启用所有严格类型检查选项**/, "noImplicitAny": false /**在表达式和声明上有隐含的any类型时报错**/, "skipLibCheck": true /**忽略所有的声明文件的类型检查**/, "forceConsistentCasingInFileNames": true /**禁止对同一个文件的不一致的引用**/, "baseUrl": "./", "paths": { "@/*": ["src/*"], "@assets/*": ["src/assets/*"], "@components/*": ["src/components/*"], "@pages/*": ["src/pages/*"], "@utils/*": ["src/utils/*"], "@store/*": ["src/store/*"] } },
10、antd menu
菜单点击跳转
const navigate = useNavigate(); //跳转 navigate(key);
菜单点击高亮当前菜单
const [current, setCurrent] = React.useState("/"); //高亮当前 setCurrent(key); <Menu mode="inline" defaultSelectedKeys={['/']} selectedKeys={[current]} className="layout-menu" items={MenuList} onClick={menuClickHandler} />
路由刷新高亮菜单
const location = useLocation(); // 获取当前路由 setCurrent(location.pathname)
11、userEffect [] 调用了两次
去掉严格模式
// <React.StrictMode> <App /> // </React.StrictMode>
12、配置多环境变量
#REACT_APP开头 REACT_APP_URL = '' REACT_APP_URL_initialize = '' REACT_APP_ENV=production
"start": "craco start", "production": "dotenv -e .env.production craco start", "build": "dotenv -e .env.production craco build",
获取参数
const base_obj = { base: process.env.REACT_APP_URL, initialize: process.env.REACT_APP_URL_initialize, };
13、外部配置路由跳转
1.安装history yarn add history
2.创建history.ts
import { createBrowserHistory } from 'history' const browserHistory = createBrowserHistory() export default browserHistory
3.创建自定义路由文件组件CutstomBrowserRouter.tsx
import * as React from "react"; import { Router } from "react-router-dom"; import browserHistory from "@/utils/history"; export default function CustomBrowserRouter({ basename="", children, window="" }) { let historyRef = React.useRef(); if (historyRef.current == null) { //@ts-ignore historyRef.current = browserHistory; } let history:any = historyRef.current; let [state, setState] = React.useState({ action: history.action, location: history.location, }); React.useLayoutEffect(() => history.listen(setState), [history]); return ( <Router basename={basename} children={children} location={state.location} navigationType={state.action} navigator={history} /> ); }
4.index.tsx使用
import CustomBrowserRouter from "@/components/CutstomBrowserRouter";
<CustomBrowserRouter>
<App />
</CustomBrowserRouter>
把原来的BrowserRouter替换为CustomBrowserRouter
14、类型“JSX.IntrinsicElements”上不存在属性“children”。
//Children 需要大写
function BaseSeacrh({ children }) { return <div className="baseSeacrh"> {<children/>} </div> }
15、路由表配置
/* eslint-disable import/no-anonymous-default-export */ import * as React from "react"; import { lazy, Suspense, ReactNode, ComponentType, LazyExoticComponent } from "react"; import NotFound from "@/pages/NotFound"; import { AuthComponent } from '@/components/AuthComponent' interface IRoute { path: string, element: ReactNode children?: IRoute[] } function lazyLoad(path: string) { const Comp: LazyExoticComponent<ComponentType<any>> = lazy(() => import("@/pages/" + path)); return ( <Suspense fallback={<div>加载中……</div>}> <Comp /> </Suspense> ); } const Routers: IRoute[] = [ { path: "/login", element: lazyLoad("Login"), }, { path: "/", element: <AuthComponent>{lazyLoad("LayoutView")}</AuthComponent>, children: [ { path: "home", element: lazyLoad("Home"), }, { path: "menu", element: lazyLoad("Menu"), }, { path: "role", element: lazyLoad("Role"), }, { path: "user", element: lazyLoad("User"), }, { path: "dict", element: lazyLoad("Dict"), }, { path: "logs", element: lazyLoad("Logs"), }, { path: "module", element: lazyLoad("Module"), }, ], }, { path: "*", element: <NotFound />, }, ]; export default Routers
使用
index.js / index.jsx
import { BrowserRouter } from 'react-router-dom'; <BrowserRouter> <App /> </BrowserRouter>
app.js/app.tsx
import { useRoutes } from "react-router-dom"; import "./App.css"; import routes from "@/router" function App() { const element = useRoutes(routes); return ( // <BrowserRouter> <div className="App"> {/* <Routes> */} {/* 鉴权 */} {/* <Route path="/" element={ <AuthComponent><LayoutView /></AuthComponent> }> <Route index element={ <AuthComponent><Home /></AuthComponent> }></Route> <Route path="/menu" element={ <AuthComponent><Menu /></AuthComponent> }></Route> <Route path="/role" element={ <AuthComponent><Role /></AuthComponent> }></Route> <Route path="/user" element={ <AuthComponent><User /></AuthComponent> }></Route> <Route path="/dict" element={ <AuthComponent><Dict /></AuthComponent> }></Route> <Route path="/logs" element={ <AuthComponent><Logs /></AuthComponent> }></Route> <Route path="/module" element={ <AuthComponent><Module /></AuthComponent> }></Route> </Route> <Route path="/login" element={<Login />}></Route> </Routes> */} {element} </div> // </BrowserRouter> ); } export default App;
16、and table增加序号
{ title: "序号", width: 70, render: (text, record, index) => `${index + 1}`, },
17、吊用组件函数useRef ref forwardRef useImperativeHandle