1. 新建项目
- npx create-react-app XXX
2. 重置项目
- 删除多余文件和代码
3. 配置项目
- 配置项目的icon:替换public文件夹中的favicon.ico文件
- 配置项目的标题:修改public文件夹中index.html文件中title标签中的值
- 配置项目的jsconfig.json(JS提示会更友好)
4. 创建项目的目录结构
- assets:资源(css/img/font)
- base-ui:当前项目和其他项目都依赖的基础UI
- components:当前项目的公共组件
- hooks
- router:路由
- services:网络请求
- store:状态管理
- utils:工具函数
- views:视图
5. 配置项目别名
craco.config.js中配置的webpack可以和react中隐藏的webpack合并
- npm install @craco/craco@alpha -D
- 新建craco.config.js文件
const path = require("path")
const resolve = pathname => path.resolve(__dirname, pathname)
module.exports = {
// webpack
webpack: {
alias: {
"@": resolve("src"),
"components": resolve("src/components"),
"utils": resolve("src/utils")
}
}
}
- 修改package.json文件中的调试入口,使其通过craco调试
6. 配置less
- 安装less:npm i craco-less@2.1.0-alpha.0
- 配置less
const path = require("path")
const CracoLessPlugin = require("craco-less")
const resolve = pathname => path.resolve(__dirname, pathname)
module.exports = {
// Less
plugins: [
{
plugin: CracoLessPlugin
}
],
// webpack
webpack: {
alias: {
"@": resolve("src"),
"components": resolve("src/components"),
"utils": resolve("src/utils")
}
}
}
7. CSS样式重置
- normalize.css:npm install normalize.css
- reset.css:自己编写
8. Router配置
- 安装路由:npm install react-router-dom
- 配置路由
- 使用HashRouter/BrowserRouter对App进行包裹,开启路由
- views中创建路由对应页面
- 在router中配置路由
// --- router/index.js --- import React from "react"; import { Navigate } from "react-router-dom"; const Home = React.lazy(() => import("@/views/home")) const Entire = React.lazy(() => import("@/views/entire")) const Detail = React.lazy(() => import("@/views/detail")) const routes = [ { path: "/", element: <Navigate to="/home"/> }, { path: "/home", element: <Home/> }, { path: "/entire", element: <Entire/> }, { path: "/detail", element: <Detail/> }, ] export default routes- 如果对某些组件进行了懒加载,需要用Suspense进行包裹
// --- index.js --- import React from 'react'; import ReactDOM from 'react-dom/client'; import { HashRouter } from "react-router-dom" import App from './App'; import "normalize.css" import "@/assets/css/index.less" const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <HashRouter> <React.Suspense fallback={<h3>Loading</h3>}> <App /> </React.Suspense> </HashRouter> </React.StrictMode> );- 页面使用路由
// --- App.jsx --- import React, { memo } from 'react' import { useRoutes } from 'react-router-dom' import routes from './router' const App = memo(() => { return ( <div className='app'> { useRoutes(routes) } </div> ) }) export default App
9. Redux状态管理
- 安装Redux:npm install @reduxjs/toolkit react-redux
- 配置Redux
- 配置store
// --- store/index.js --- import { configureStore } from "@reduxjs/toolkit"; import homeReducer from "./modules/home" const store = configureStore({ reducer: { home: homeReducer } }) export default store- RTK配置对应的reducer
// --- store/modules/home.js --- import { createSlice } from "@reduxjs/toolkit" const homeSlice = createSlice({ name: "home", initialState: { }, reducers: { } }) export default homeSlice.reducer- 通过Provider组件把store挂载到App组件上
// --- index.js --- import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; import { HashRouter } from "react-router-dom" import { Provider} from "react-redux" import App from './App'; import "normalize.css" import "@/assets/css/index.less" import store from './store'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Suspense fallback={<h3>Loading</h3>}> <HashRouter> <Provider store={store}> <App /> </Provider> </HashRouter> </Suspense> </React.StrictMode> );
10. 配置网络请求
- 安装axios:npm install axios
- 配置service
- 新建index.js文件为service统一出口
// --- index.js --- import hyRequest from "./request" export default hyRequest export * from "./modules/home"- 新建request文件夹封对axios进行二次封装
// --- request/index.js --- import axios from "axios"; import { BASE_URL, TIMEOUT } from "./config" class HYRequest { constructor(baseURL, timeout) { this.instance = axios.create({ baseURL, timeout }) } request(config) { return this.instance.request(config) } response(config) { return this.instance.response(config) } get(config) { return this.request({ ...config, method: "get" }) } post(config) { return this.request({ ...config, method: "post" }) } } export default new HYRequest(BASE_URL, TIMEOUT) // --- request/config.js --- export const BASE_URL = "XXXXXX" export const TIMEOUT = 10000- 新建modules文件夹使得每一个模块都有自己独立的文件管理所有的网络请求
// --- modules/home.js --- import hyRequest from ".."; export function getHomeGoodPriceData() { return hyRequest.get({ url: "XXXXXX" }) }