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 [email protected]
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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章