React项目规范:目录结构、根目录别名、CSS重置、路由、redux、二次封装axios

React项目(一)

  • 一、创建项目
  • 二、目录结构
  • 三、craco配置别名并安装less
    • 1.craco安装
    • 2.配置别名
    • 3.安装less
  • 四、CSS样式重置
  • 五、配置路由
  • 六、配置Redux
    • 1.创建大仓库
    • 2.创建小仓库
      • (1)方式1:RTK
      • (2)方式2:普通写法
  • 七、配置axios

一、创建项目

先创建项目:create-react-app 项目名,然后换个图标,换个标题

配置jsconfig.json:这个文件在Vue通过脚手架创建项目时自动生成, React是没有自动生成, jsconfig.json是为了让vs code的代码提示更友好, 按需求决定是否配置;

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

二、目录结构

src文件夹的目录进行初始化:

assets: 存放静态资源 (如css, img等等)

baseUI: 存放一些通用的组件, 不只是本项目, 其他项目也会使用的组件

components: 存放本项目中通用的组件

hooks: 自定义的hook函数

router: 路由相关

services: 网络请求相关

stores: 状态管理, redux相关

utils: 封装的工具函数

views: 页面相关

三、craco配置别名并安装less

1.craco安装

1、安装craco:npm install craco

修改package.json:

/* package.json */
"scripts": {
-   "start": "react-scripts start",
-   "build": "react-scripts build",
-   "test": "react-scripts test",
	👇👇👇👇👇👇
+   "start": "craco start",
+   "build": "craco build",
+   "test": "craco test",
}

2.配置别名

在项目中层级嵌套会很深, 我们导入文件通常会有../../../甚至更多的上一级目录; 因此我们配置别名解决这个问题, 我的配置是使用@符号表示根目录

在项目根目录创建一个 craco.config.js 用于修改默认配置,该文件中的一些配置(如webpack)会和脚手架中的配置合并。修改别名的操作如下:

const path = require('path');

module.exports = {
    webpack: {
        alias: {
            "@": path.resolve(__dirname, 'src'),
            'components': path.resolve(__dirname, 'src/components'),
            'store':path.resolve(__dirname,'src/store'),
             ......
        }
    }
}

3.安装less

先安装:npm i craco-less

按照如下方式去craco.config.js中去配置一下:

const path = require('path');
const CracoLessPlugin = require('craco-less');

module.exports = {
    //下面的配置和脚手架webpack合并
    webpack: {
        alias: {
            "@": path.resolve(__dirname, 'src'),
            'components': path.resolve(__dirname, 'src/components'),
            'store':path.resolve(__dirname,'src/store'),
        }
    },

    //配置less
    plugins: [
        {
            plugin: CracoLessPlugin
        }
    ]
}

🆗,应该可以用了

四、CSS样式重置

下载normalize.css, 再在src中的index.js文件引入normalize.css,这是给我们提供好的初始样式的一个模板吧。

npm i normalize.css

然后如果我们想自己自定义一些baseCSS,可以再新建一个文件

在这里插入图片描述

并且在normalize.css之后引入:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

import 'normalize.css';  //先引入模板
import '@/assets/css/reset.css' //引入自定义样式

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <App />
);

五、配置路由

安装

npm install react-router-dom

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/reset.css' //引入自定义样式

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <HashRouter>
    <App />
  </HashRouter>
);

新建几个路由组件,并配置他们的路由信息

在这里插入图片描述

最后去App.jsx中通过useRoutes这个hook,引入路由配置。

import React, { memo } from 'react';
import { useRoutes } from 'react-router-dom';
import routes from '@/router';

const App = memo(() => {
  return (
    <div>
      <div className="app">
        <div className="header">Header</div>
        <div className="content">
          {useRoutes(routes)}
        </div>
        <div className="footer">Footer</div>
      </div>
    </div>
  )
})

export default App

如果要用路由懒加载,则再加两步操作:

import React from "react";
// import Home from "@/views/Home";
// import Detail from "@/views/Detail";
// import Entire from "@/views/Entire";
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'));

let routes = [
    {
        //重定向
        path:'/',
        element:<Navigate to='/home' />
    },
    {
        path: '/home',
        element: <Home/>
    },
    {
        path:'/detail',
        element: <Detail/>
    }, 
    {
        path:'/entire',
        element:<Entire/>
    }
]

export default routes;

在这里插入图片描述

六、配置Redux

安装:这里安装RTK同时也会安装redux的,除此之外我们还要一起安装react-redux

npm install react-redux @reduxjs/toolkit

1.创建大仓库

使用RTK的方式创建大store:

import { configureStore } from "@reduxjs/toolkit";
import homeReducer from './modules/home';
import entireReducer from './modules/entire'

const store = configureStore({
    reducer: {
        home: homeReducer,
        entire: entireReducer,
    }
})

export default store;

创建完了别忘了去入口文件包个标签

在这里插入图片描述

2.创建小仓库

为了复习之前的知识,这里我们用两种方式创建reducer函数:

在这里插入图片描述

(1)方式1:RTK

import { createSlice } from "@reduxjs/toolkit";

const homeSlice = createSlice({
    name: 'home',
    initialState: {
        userName: 'zzy'
    },
    reducers: {
        changeUserName(state, action) {
            state.userName = action.payload;
        }
    }
})

export default homeSlice.reducer;

(2)方式2:普通写法

entire/constants.js
const CHANGECOUNTER = 'changecounter';
export {CHANGECOUNTER};
entire/reducer.js
import * as actionTypes from './constants';

let initialState = {
    counter: 0
}

function reducer(state = initialState, action) {
    switch(action.type) {
        case actionTypes.CHANGECOUNTER:
            return {...state, counter: action.num}
        default: 
            return state;
    }
}

export default reducer;
entire/actionCreators.js
import * as actionTypes from './constants';

export const changeCounter = (num) => {
    return {
        type: actionTypes.CHANGECOUNTER,
        num
    }
}
entire/index.js
import reducer from "./reducer";
export default reducer;

七、配置axios

首先安装axios:npm i axios

在这里插入图片描述

二次封装axios:

api/request/index.js
import axios from 'axios';
import { BASEURL, TIMEOUT } from './config';

class HYRequest {
    constructor(baseURL, timeout) {
        this.instance = axios.create({
            baseURL,
            timeout,
        })

        this.instance.interceptors.response.use(res => {
            return res.data;
        })
    }

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

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

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

//用变量存储baseURL的话,如果有其他的url,只需要导出其他的实例就可以了
export default new HYRequest(BASEURL, TIMEOUT);
api/request/config.js
const BASEURL = 'http://codercba.com:1888/airbnb/api';
const TIMEOUT = 6000;

export {BASEURL, TIMEOUT}

说实话这里的封装还挺巧妙的,和之前做vue项目的封装不一样,这里面用类来存储axios的实例,发请求都会调用类的实例的方法,然后该方法再调用axios实例上的方法。不过目前好像还没get到这样封装的好处。。

找个组件测试一下:

import React, { memo, useEffect } from 'react';
import hyRequest from '@/api';

const Home = memo(() => {

  useEffect(() => {
    hyRequest.get({url:'/home/highscore'}).then(res => {
      console.log(res);
    })
  },[])

  return (
    <div>
      <h1>Home</h1>
    </div>
  )
})

export default Home

🆗,现在项目搭建的就差不多了,接下来就开始写里面的东西,放到下一篇文章中吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/840.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

toString()、equals()是什么,为啥需要重写,多种方法来重写

https://m.runoob.com/java/java-object-class.html toString() 1.为什么会有toString 子类继承父类就可以使用父类所有非私有的属性的方法。 在Java中所有类都直接或者间接继承Object类&#xff0c;可以说只要是Object类里面定义的非私有的属性和方法&#xff0c;任何类都可…

Linux上如何使用Stable Diffusion WebUI

在我把所有的坑都踩了一遍之后&#xff0c;决定记录一下linux上的Stable Diffusion webui是怎么搞的。 前提条件 已安装CUDA 已安装git 已安装Anaconda 直接安装Anaconda不要指望Linux自带的Python。虽然Linux自带的Python&#xff0c;但是缺胳膊少腿&#xff0c;所以还是直接…

IntelliJ IDEA创建Servlet

目录 ——————————————————————————————— 一、创建Java项目 1、创建java项目 2、选择java 3、next 4、给项目命名 5、新创建完java项目的目录结构 二、变java为servlet项目 1、变servlet项目 2、选择Web Application 3、更新完成后的目录…

尚融宝04-mybatis-plus插件和条件构造器

目录 一、分页插件 1、添加配置类 2、添加分页插件 3、测试分页 二、XML自定义分页 1、UserMapper中定义接口方法 2、定义XML 3、测试 三、乐观锁 1、场景 2、乐观锁方案 3、乐观锁实现流程 4、优化流程 四、wapper介绍 1、Wrapper家族 2、创建测试类 五、Qu…

Linux驱动开发

一、驱动分类Linux中包含三大类驱动&#xff1a;字符设备驱动、块设备驱动和网络设备驱动。其中字符设备驱动是最大的一类驱动&#xff0c;因为字符设备最多&#xff0c;从led到I2C、SPI、音频等都属于字符设备驱动。块设备驱动和网络设备驱动都要比字符设备驱动复杂。因为其比…

线程的状态

目录 1.线程状态的种类 2.线程的状态图 3.状态的详细说明 1.线程状态的种类 初始(NEW):新建一个线程,但还没有调用start方法 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态统称为"运行".线程对象创建后,其他线程调用了该对象的start()方法.该…

抽丝剥茧还原真相,记一次神奇的崩溃

作者&#xff1a;靳倡荣 本文详细回放了一个崩溃案例的分析过程。回顾了C多态和类内存布局、pc指针与芯片异常处理、内存屏障的相关知识。 一、不讲“武德”的崩溃 1.1 查看崩溃调用栈 客户反馈了一个崩溃问题&#xff0c;并提供了core dump文件&#xff0c;查看崩溃调用栈如下…

大数据-重新学习hadoop篇(第一天)-未完成

前言&#xff1a;首先这次重新学习为了后面校招&#xff0c;我会把我每天复习学到的一些觉得重要的知识点进行总结下来&#xff0c;持续更新&#xff0c;为实习做准备&#xff0c;加深记忆&#xff0c;从今天开始可能就不会法leetcode的相关题解了&#xff0c;但是每天还是会做…

【动态规划】不同路径,编辑距离题解及代码实现

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

【前端】深入浅出缓存原理

缓存的基本原理 对于前端来说&#xff0c;缓存主要分为浏览器缓存&#xff08;比如 localStorage、sessionStorage、cookie等等&#xff09;以及http缓存&#xff0c;也是本文主要讲述的。 当然叫法也不一样&#xff0c;比如客户端缓存大概包括浏览器缓存和http缓存 所谓htt…

“选用育留”,让AI搞定人力资源那点事

人工智能可以渗透应用到各行各业&#xff0c;在人力资源领域&#xff0c;技术已经重构了我们对人力资源的想象力&#xff0c;许多企业都在应用AI技术改善人力工作&#xff0c;人力资源的数智化不仅仅是将一部分日常事务性的工作交由AI处理&#xff0c;节约工作时间&#xff0c;…

到底什么是线程?线程与进程有哪些区别?

上一篇文章我们讲述了什么是进程&#xff0c;进程的基本调度 http://t.csdn.cn/ybiwThttp://t.csdn.cn/ybiwT 那么本篇文章我们将了解一下什么是线程&#xff1f;线程与进程有哪些区别&#xff1f;线程应该怎么去编程&#xff1f; 目录 http://t.csdn.cn/ybiwThttp://t.csdn…

HTTP详解

一&#xff0c;什么是HTTPHTTP(全称为“超文本传输协议”)&#xff0c;是一种应用非常广泛的应用层协议&#xff0c;之前在《初识网络原理》的博客(初识网络原理_徐憨憨&#xff01;的博客-CSDN博客)中&#xff0c;有详细讲解过TCP/IP五层模型&#xff0c;其中应用层描述了数据…

算法---完成任务的最少工作时间段

题目&#xff1a; 你被安排了 n 个任务。任务需要花费的时间用长度为 n 的整数数组 tasks 表示&#xff0c;第 i 个任务需要花费 tasks[i] 小时完成。一个 工作时间段 中&#xff0c;你可以 至多 连续工作 sessionTime 个小时&#xff0c;然后休息一会儿。 你需要按照如下条件…

即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示

结论先行 原则&#xff1a; server拉取的消息一定是连续的原则&#xff1a; 端侧记录的消息的连续段有两个作用&#xff1a; 1. 记录消息的连续性&#xff0c; 即起始中间没有断层&#xff0c; 2. 消息连续&#xff0c; 同时意味着消息是最新的&#xff0c;消息不是过期的。同…

CKA最新考试费用是多少?考试内容是什么?

CKA认证考试是由Linux基金会和云原生计算基金会(CNCF)创建的&#xff0c;以促进Kubernetes生态系统的持续发展。该考试是一种远程在线、有监考、基于实操的认证考试&#xff0c;需要在运行Kubernetes的命令行中解决多个任务。CKA认证考试是专为Kubernetes管理员、云管理员和其他…

YOLOv8初体验:检测、跟踪、模型部署

安装 YOLOv8有两种安装方式&#xff0c;一种是直接用pip命令安装&#xff1a; pip install ultralytics另外一种是通过源码安装&#xff1a; git clone https://github.com/ultralytics/ultralytics cd ultralytics pip install -e .[dev]安装完成后就可以通过yolo命令在命令…

Yolov8详解与实战

文章目录摘要模型详解C2F模块Losshead部分模型实战训练COCO数据集下载数据集COCO转yolo格式数据集&#xff08;适用V4&#xff0c;V5&#xff0c;V6&#xff0c;V7&#xff0c;V8&#xff09;配置yolov8环境训练测试训练自定义数据集Labelme数据集摘要 YOLOv8 是 ultralytics …

Git规范

Commit 规范 常见的开源社区 commit message 规范&#xff1a; 比如 Angular 规范&#xff1a; 语义化&#xff1a;commit message 被归为有意义的类型用来说明本次 commit 的类型。 规范化&#xff1a;commit message 遵循预先定义好的规范&#xff0c;比如格式固定、都属…

GIS(地理信息系统/地理信息科学)职称评审三:中科院和人社部职称评审结果公示对比

目录1.前言2.中科院3.人社部3.1 初级、中级3.2 高级、正高级3.3 公示时间4. 证书5. 程序员要不要评职称&#xff1f;6.总结1.前言 我们在前两篇已经讲过了GIS&#xff08;地理信息系统/地理信息科学&#xff09;怎么评职称&#xff1f;以及中科院和人社部职称评审所需材料内容对…
最新文章