React創(chuàng)建項(xiàng)目流程與規(guī)范
項(xiàng)目規(guī)范
項(xiàng)目規(guī)范: 在項(xiàng)目中都會(huì)有一些開(kāi)發(fā)規(guī)范和代碼風(fēng)格, 下面介紹一下我采用的規(guī)范與風(fēng)格
-
文件夾、文件名稱(chēng)統(tǒng)一小寫(xiě)、多個(gè)單詞以連接符(-)連接, 組件采用大駝峰;
-
JavaScript變量名稱(chēng)采用小駝峰標(biāo)識(shí),常量全部使用大寫(xiě)字母;
-
CSS采用普通CSS和styled-component結(jié)合來(lái)編寫(xiě)(全局采用普通CSS或Less、局部采用styled-component);
-
整個(gè)項(xiàng)目不再使用class組件,統(tǒng)一使用函數(shù)式組件,并且全面擁抱Hooks;
-
所有的函數(shù)式組件,為了避免不必要的渲染,全部使用memo進(jìn)行包裹;
-
組件內(nèi)部的狀態(tài),使用useState、業(yè)務(wù)數(shù)據(jù)全部放在redux中管理;
-
函數(shù)組件內(nèi)部邏輯代碼基本按照如下順序編寫(xiě)代碼:
組件內(nèi)部state管理;
redux的hooks代碼;
其他hooks相關(guān)代碼(比如自定義hooks);
其他邏輯代碼;
返回JSX代碼;
-
redux代碼規(guī)范如下:
redux目前我們學(xué)習(xí)了兩種模式, 根據(jù)自己的情況選擇普通模式還是rtk模式
每個(gè)模塊有自己獨(dú)立的reducer或者slice,之后合并在一起;
redux中會(huì)存在共享的狀態(tài)、從服務(wù)器獲取到的數(shù)據(jù)狀態(tài);
-
網(wǎng)絡(luò)請(qǐng)求采用axios
對(duì)axios進(jìn)行二次封裝;
所有的模塊請(qǐng)求會(huì)放到一個(gè)請(qǐng)求文件中單獨(dú)管理;
-
項(xiàng)目使用AntDesign或者M(jìn)UI(Material UI)
其他規(guī)范在項(xiàng)目中根據(jù)實(shí)際情況決定和編寫(xiě)
項(xiàng)目配置
創(chuàng)建項(xiàng)目的方式:create-react-app
項(xiàng)目配置:
配置項(xiàng)目的icon, 將圖標(biāo)換為自己項(xiàng)目的圖標(biāo)
配置項(xiàng)目的標(biāo)題: 在public文件夾下的index.html中配置項(xiàng)目的標(biāo)題
<title>網(wǎng)易云音樂(lè)</title>
配置jsconfig.json:這個(gè)文件在Vue通過(guò)腳手架創(chuàng)建項(xiàng)目時(shí)自動(dòng)生成, React是沒(méi)有自動(dòng)生成,
jsconfig.json
是為了讓vs code的代碼提示更友好, 按需求決定是否配置;
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"jsx": "preserve",
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}
通過(guò)craco配置別名和less文件(不需要集成less只需要配置別名):
在項(xiàng)目中層級(jí)嵌套會(huì)很深, 我們導(dǎo)入文件通常會(huì)有../../../
甚至更多的上一級(jí)目錄; 因此我們配置別名解決這個(gè)問(wèn)題, 我的配置是使用@
符號(hào)表示根目錄
首先安裝craco:
npm i @carco/craco -D
如果使用的最新的React版本, 則需要
npm i @craco/craco@alpha -D
來(lái)安裝
安裝完成, 在項(xiàng)目根目錄下創(chuàng)建
craco.config.js
文件
const path = require('path')
const reslove = pathname => path.resolve(__dirname, pathname)
module.exports = {
webpack: {
alias: {
"@": reslove("src")
}
}
}
然后修改根目錄下
package.json
文件中的腳本, 修改為craco啟動(dòng), 修改如下:
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
別名配置完成, 接下來(lái)我們配置一下less, 不需要集成less跳過(guò)即可
首先進(jìn)行安裝:
npm i craco-less
最新版本React同樣會(huì)有適配問(wèn)題, 安裝方式:
npm i craco-less@2.1.0-alpha.0
安裝完成按照如下方式配置less, 配置完成創(chuàng)建一個(gè)less文件測(cè)試一下, 樣式生效就配置成功了
const path = require('path')
const CracoLessPlugin = require('craco-less')
const reslove = pathname => path.resolve(__dirname, pathname)
module.exports = {
// less
plugins: [
{
plugin: CracoLessPlugin
}
],
webpack: {
alias: {
"@": reslove("src")
}
}
}
目錄結(jié)構(gòu)
接下來(lái)對(duì)項(xiàng)目src文件夾下進(jìn)行目錄結(jié)構(gòu)的劃分, 我是按照如下方式進(jìn)行劃分的:
assets: 存放靜態(tài)資源 (如css, img等等)
base-ui: 存放一些通用的組件, 不只是本項(xiàng)目, 其他項(xiàng)目也會(huì)使用的組件
components: 存放本項(xiàng)目中通用的組件
hooks: 自定義的hook函數(shù)
router: 路由相關(guān)
services: 網(wǎng)絡(luò)請(qǐng)求相關(guān)
stores: 狀態(tài)管理, redux相關(guān)
utils: 封裝的工具函數(shù)
views: 頁(yè)面相關(guān)
樣式重置
對(duì)默認(rèn)CSS樣式進(jìn)行重置:
下載
normalize.css
, 再在src中的index文件引入normalize.css
可以通過(guò)npm安裝
npm i normalize.css
import React from 'react'
import ReactDOM from 'react-dom/client'
// 引入樣式重置文件
import "normalize.css"
import App from './App'
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(<App/>)
創(chuàng)建一個(gè)
reset.css
文件, 用來(lái)自己編寫(xiě)一些樣式的重置
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
color: #000;
outline: none;
}
ul, li {
list-style: none;
}
input {
outline: none;
border: none;
}
i {
font-style: normal;
}
并且引入
import React from 'react'
import ReactDOM from 'react-dom/client'
// 引入樣式重置文件
import "normalize.css"
import "./assets/css/reset.css"
import App from './App'
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(<App/>)
Router配置
安裝:
npm i react-router-dom
安裝完成配置映射關(guān)系即可, 示例代碼如下:
import React from "react"
import { Navigate } from "react-router-dom"
// 懶加載
const Home = React.lazy(() => import("@/views/home"))
const Detail = React.lazy(() => import("@/views/detail"))
const Entire = React.lazy(() => import("@/views/entire"))
const routes = [
{
path: "/",
element: <Navigate to="/home"/>
},
{
path: "/home",
element: <Home/>
},
{
path: "/detail",
element: <Detail/>
},
{
path: "/entire",
element: <Entire/>
}
]
export default routes
配置完成使用, 還需要在src目錄下index.js文件中, 對(duì)App組件進(jìn)行包裹
import React, { Suspense } from "react"
import ReactDOM from "react-dom/client"
import { BrowserRouter } from "react-router-dom"
import App from "./App"
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(
<BrowserRouter>
<Suspense fallback="lodaing">
<App/>
</Suspense>
</BrowserRouter>
)
Redux狀態(tài)管理
Redux有兩種模式
普通方式: 目前項(xiàng)目中依然使用率非常高;
@reduxjs/toolkit方式: 推薦方式, 未來(lái)的趨勢(shì);(下面簡(jiǎn)單演示一樣rtk模式)
rtk模式安裝:
npm i @reduxjs/toolkit react-redux
安裝完成后再store文件夾下的index.js中進(jìn)行配置
import { configureStore } from '@reduxjs/toolkit'
const store = configureStore({
reducer: {}
})
export default store
同樣需要對(duì)根組件App進(jìn)行包裹
import React, { Suspense } from "react"
import ReactDOM from "react-dom/client"
import { Provider } from "react-redux"
import App from "./App"
import store from "./stores"
const root = ReactDOM.createRoot(document.querySelector("#root"))
root.render(
<Provider store={store}>
<App/>
</Provider>
)
axios配置
項(xiàng)目中我采用axios發(fā)送網(wǎng)絡(luò)請(qǐng)求
首先安裝axios:
npm i axios
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-793219.html
一般會(huì)對(duì)axios進(jìn)行二次封裝, 代碼如下文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-793219.html
import axios from "axios";
import { BASE_URL, TIMEOUT } from "./config";
class YQRequest {
// 傳入默認(rèn)配置信息, 創(chuàng)建新的實(shí)例
constructor(baseURL, timeout=10000) {
this.instance = axios.create({
baseURL,
timeout
})
// 響應(yīng)成功的攔截, 返回res.data
// this.instance.interceptors.response.use(res => {
// return res.data
// }, err => {
// return err
// })
}
// 1.封裝request
request(config) {
// 返回一個(gè)Promise, 對(duì)數(shù)據(jù)轉(zhuǎn)換
return new Promise((reslove, reject) => {
this.instance.request(config).then(res => {
reslove(res.data)
}).catch(err => {
reject(err)
})
})
}
// 2.封裝get
get(config) {
// 調(diào)用自己的request函數(shù)
return this.request({ ...config, methods: "get" })
}
// 3.封裝psot
post(config) {
// 調(diào)用自己的request函數(shù)
return this.request({ ...config, methods: "post" })
}
}
export default new YQRequest(BASE_URL, TIMEOUT)
export const BASE_URL = "http://codercba.com:1888/airbnb/api"
export const TIMEOUT = 10000
到了這里,關(guān)于React框架創(chuàng)建項(xiàng)目詳細(xì)流程-項(xiàng)目的基本配置-項(xiàng)目的代碼規(guī)范的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!