此文章适合刚接触react 项目小白童鞋 项目搭建
create-react-app
# https://www.html.cn/create-react-app/docs/adding-typescript/ 官档
Trap
typescript 安装依赖需要安装对应ts 版本
建议先提取webpack.config.js 文件
引入 less 需要修改对应配置
目录
1、安装 create-react-app my-app --typescript
2、安装less
3
搞起
create-react-app my-app --typescript
提取 webpack 配置 yarn eject >>> 文件夹会多出一个config文件夹
安装 处理 less ----------------------------
npm install less less-loader -dev
默认自带 module.css module.sass 引入方式
安装less依赖后 可能出问题会有两点原因
1、 版本过高
调整到 yarn add less-loader@5.0.0
2、typescript 下引用[fileName].module.less 提示引用不到资源
原因:未在全局暴露less 接口
处理方式: react-app-env.d.ts >>>> 添加
declare module '*.module.less' {
const classes: { readonly [key: string]: string };
export default classes;
}
reacrt+js 做完这下面操作就行
引入后需修改 webpack.config.js
添加这两段
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'less-loader'
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'less-loader'
),
},
引入redux 状态管理
ts 版本 npm install @types/react-redux
在根 index.tsx 页面引入
import { Provider } from "react-redux"
// Proveider 将App包裹 保证全局都能调用到
<Provider store={store}>
<React.StrictMode>
<App />
</React.StrictMode>
</Provider>,
创建 reducers
新建文件夹 reducers
reducers >>> index.tsx
根store 创建
/** index.tsx */
/**创建唯一store
* combineReducers 把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer
* 函数,然后就可以对这个 reducer 调用 createStore。
*/
import { configureStore, combineReducers, Reducer } from '@reduxjs/toolkit';
import rootReducer, { staticReducers } from './rootReducer'
/**
* rootReducer 全局保存用户信息 配置信息
* staticReducers
*/
// configureStore()在你的react项目里,只能出现一次,
const store = configureStore({ //单一原则
reducer: rootReducer,
devTools: process.env.NODE_ENV !== 'production',
})
/**
* @param 一些说明:
* 1. 当前的项目架构使用的是单个 store + 初始化时会生成的 rootReducer(这个reducer里只有公用的reducer)
* 1.1 如果需要使用 - 路由懒加载代码分割 - 的模式,那么会导致动态加载的业务模块对应的 reducer 不存在,所以会需要将当前 store 进行合并且重新注入,让业务模块的reducer 可以存在
*
* 2. 还有一种设计模式可以参考:项目中分为多个 store , webpack 的 entry 是动态的, 在 build 时使用 npm run build --moduleName
* 2.1 那么此时每个业务模块的 rootReducer 也就是被 Provider 提供的 store 始终都是会包含当前业务模块的 reducer ,就不会出现以上第一种的情况,也就不需要这个 injectReducer 这个操作
*
* - 不倾向某一种 redux 的设计,按照业务来决定即可
*
*/
declare interface LooseObject {
[key: string]: any;
}
const asyncReducers: LooseObject = {};
export function injectReducer<State>(key: string, reducer: Reducer<State>) {
asyncReducers[key] = reducer;
const newRootReducer = combineReducers({
...staticReducers,
...asyncReducers,
});
store.replaceReducer(newRootReducer)
}
/**
*replaceReducer
*如果您的应用程序实现了代码拆分,并且您想要
*动态加载一些减速器。 如果您可能还需要此
*为Redux实现热重载机制。
*/
// 普通 dispatch
// 获取一个变量的类型时
// 获取 store.dispatch 的类型 并定义为 AppDispatch
export type AppDispath = typeof store.dispatch;
// 如果没有导出ReturnType 而需要获取ReturnType返回类型的值 // 获取rootReducer 类型
export type RootState = ReturnType<typeof rootReducer>;
export default store;
基础版
https://blog.csdn.net/qq_42359718/article/details/105956421
代码分割后 需要动态注入
局部reducer 创建后 用 上文定义的 injectReducer 引用 (没有案例难理解, 晚点再分解一张)
injectReducer('supplierData', reducer);
路由
npm install @types/react-router-dom
import { BrowserRouter } from "react-router-dom";
const render = () => {
// const App = require("./App").default;
ReactDOM.render(
<Provider store={store}>
{/* // 需要用BrowserRouter 包裹App 不然无法在内部使用 Switch Route 等组件构建Router */}
<BrowserRouter>
<React.StrictMode>
<App />
</React.StrictMode>
</BrowserRouter>
</Provider>,
document.getElementById("root")
);
}
render()
路由eg:
import React from 'react';
import { Switch, Route, Redirect } from 'react-router-dom'
import LayOut from '../Layout/index'
import NotFound from '../../NotFound/index'
const Admin = () => {
return (
<>
<Switch>
<Route exact path='/'>
<Redirect to="/Admin" />
</Route>
<Route exact path='/Admin'>
<LayOut />
</Route>
<Route path="/404">
<NotFound />
</Route>
<Redirect to="/404" />
</Switch>
</>
)
}
export default Admin