create-react-app + typescript + less + react-router-dom + @reduxjs/toolkit 从零开始项目构建

此文章适合刚接触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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值