关于React18 router6 rtk技术栈开启新项目全流程

创建项目流程:

创建脚手架:

执行npx create-react-app [项目名称]创建项目

整理文件

删除public文件夹中相关的无效文件和代码,
其中:
public保留index.html,favicon.ico。
src文件中保留index.js。
改写App为jsx的memo包裹项目。

配置目录文件:

创建文件夹并同上命名,用以管理资源
配置开发引导文件
根目录中配置jsconfig.json文件,实现更好的代码提示和组件索引

a) 配置内容如下:

{
    "compilerOptions": {
        "target": "es5",
        "module": "esnext",
        "baseUrl": "./",
        "moduleResolution": "node",
        "paths": {
            "@/*": [
                "src/*"
            ]
        },
        "jsx": "preserve",
        "lib": [
            "esnext",
            "dom",
            "dom.iterable",
            "scripthost"
        ]
    }
}

安装craco:

执行命令yarn add @craco/craco@alpha -D,在开发依赖环境下安装craco用以覆写config文件内容
准备覆写文件:

根目录创建craco.config.js文件并如下配置:

const path = require("path")

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")
        }
    }
}

并将package.json文件中的script里start/build/test的react-scripts启动更改为craco启动

配置less:

执行命令yarn add craco-less@2.1.0-alpha.0
由于之前已经在craco中配置过less的相关插件,建议在css中创建一个less并引用之后进行测试一下,保证less配置的正确运行(webpack相关的配置修改之后记得重启项目)
Css样式重置

b) 执行命令yarn add normalize.css,并在src下index.js中添加

import “normalize.css” 引用.

c) 在assets/css中创建reset.less文件,并添加:

body, button, dd, dl, dt, form, h1, h2, h3, h4, h5, h6, hr, input, li, ol, p, pre, td, textarea, th, ul {
    margin: 0;
    padding: 0;
}

a {
    text-decoration: none;
}

img {
    vertical-align: top;
}

ul, li {
    list-style: none;
}

并在assets/css/index.less中引用该文件。

d) 对于各个组件,使用styled-components库实现css-in-js的编写方式

i. 执行命令yarn add styled-components
ii. 模块入口文件创建文件style.js代码如下
import styled from ‘styled-components’
export const TestAWrapper = styled.div`
	//css code
`
iii. 模块入口文件引用之后,建议最外层根标签使用TestAWrapper来进行包裹,可以提高代码阅读性

配置路由:

e) 执行命令yarn add install react-router-dom
f) Src/index.js下添加

import { HashRouter } from “react-router-dom”
并且使用HashRouter将App包裹

g) 在src/router中创建index.js并添加代码
import { lazy } from "react";
import { Navigate } from "react-router-dom";

const TestA = lazy(() => import("@/views/test-a"))

const routes = [
    {
        path: '/',
        element: <Navigate to="/testa"/>
    },
    {
        path: '/testa',
        element: <TestA />
    },
]

	export default routes;
h) A中添加代码
import { useRoutes } from 'react-router-dom'
import routes from '@/router'
		//并且在路由展示区域添加代码
			{ useRoutes(routes) }
		//来引入自定义路由配置文件

配置redux:

i) 执行命令yarn add @reduxjs/toolkit react-redux
j) 在store/index.js中整合所有的redux,作为统一入口文件
import { configureStore } from '@reduxjs/toolkit'
import testaReducer from './test-a'

const store = configureStore({
    reducer: {
        testa: testaReducer
    }
})

export default store
k) 在store建立和views中相同的文件夹树结构,并且在对应的树结点文件夹中创建入口文件来做redux片段代码的编写,例如,在store/testa/index.js中创建代码:
import { createSlice } from '@reduxjs/toolkit'

const TestASlice = createSlice({
    name: 'testa',
    initialState: {
        count: 0,
    },
    reducers: {
    },
    extraReducers: builder => {
        builder.addCase(
            //todo
        )
    }
})

export default TestASlice.reducer

配置axios:

l) 执行命令:yarn add axios
m) 在service中创建入口文件index.js,模块请求方法文件夹modules,请求二次封装文件夹request,具体代码根据业务逻辑会发生变化
n) 以易查内部系统为例,二次封装请求命名为ycrequest

service/index.js文件代码
import ycrequest from “./request”;

export default ycrequest
service/request中包含config.js和index.js两个文件
其中config.js文件用来配置网络请求的常量参数
export const BASE_URL = “http://192.168.1.215:6100”
export const TIMEOUT = 10000

	index.js文件中代码为
	import axios from 'axios';
import { BASE_URL, TIMEOUT } from './config';

class YCRequest {
    constructor(baseURL, timeout) {
        this.instance = axios.create({
            baseURL,
            timeout
        })
        this.instance.interceptors.response(res => {
            //  请求成功判断
            if (res.code === "200")
                return res.data
            else
                throw new Error(res.message)
        }, err => {
            //error todo
            throw new Error(err)
        })
    }

    request(config) {
        return this.instance.request(config)
    }

    get(config) {
        return this.request({
            ...config, 
            method: 'get'
        })
    }

    post(config) {
        return this.request({
            ...config,
            method: 'post'
        })
    }
}
const ycrequest = new YCRequest( BASE_URL, TIMEOUT )

export default ycrequest
	该网络请求使用类实例对三方库调动的方法进行二次封装,以防止三方库出现异常后替换需要过大代价的情况。
	Modules文件夹中用于存放不同模块需要使用的网络请求,只存放网络请求发起方法,网络请求处理的方法应封装在reduxSlice中。
o) 代理劫持配置

详情查看src/setupProxy文件

异步网络编写:

p) 网络请求方法编写在services/modules中对应的结点文件夹中,请求方法举例:
import { stringify } from "qs";
import ycrequest from "../request";


export function getUserInfo(payload) {
    return ycrequest.get({
        url: `/auth/user/login?${stringify(payload)}`
    })
}
q) 组件中派发redux中的action来发起网络请求代码举例:
const dispatch = useDispatch()

useEffect(() => {
    const requestParams = {
      name: 'sg',
      password: '123456'
    }
    dispatch(fetchUserInfo(requestParams))
  	}, [dispatch])
r) 将网络请求结果保存到redux中的代码写在store中对应的结点文件夹中,保存方法举例:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'

import { getUserInfo } from '@/services'

export const fetchUserInfo = createAsyncThunk("fetchUserInfo", async payload => {
    const res = await getUserInfo(payload)
    return res.user
})

const TestASlice = createSlice({
    name: 'testa',
    initialState: {
        userInfo: {}
    },
    reducers: {
        changeUserInfo(state, { payload }) {
            state.userInfo = payload
        }
    },
    extraReducers: builder => {
        builder.addCase(fetchUserInfo.fulfilled, (state, { payload }) => {
                    //request success todo
                    state.userInfo = payload
                })
                .addCase(fetchUserInfo.rejected, () => {
                    //request failed todo
                    console.log("request rejected")
                })
    }
})

export const { changeUserInfo } = TestASlice.actions

export default TestASlice.reducer

组件中从Redux数据获取:
代码示例:

const { nickName, sex, phonenumber } = useSelector(state => ({
    nickName: state.testa.userInfo.nickName,
    sex: state.testa.userInfo.sex,
    phonenumber: state.testa.userInfo.phonenumber,
  }), shallowEqual)

整个项目开发搭建流程大致如此,该版本项目搭建时间为2023年1月上旬,记录一下,未来变更会另行记录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值