react项目规范新手教程

news2024/11/24 3:03:18

简介

React是一种流行的JavaScript库,用于构建用户界面。搭建一个React项目并不难,但确保项目的结构和配置正确可以帮助你更有效地开发和维护应用程序。以下是搭建React项目的一些步骤:

项目规范:项目中有一些开发规范和代码风格

  1. 文件夹、文件名称统一小写、多个单词以连接符(-)连接;
  2. JavaScript变量名称采用小驼峰标识,常量全部使用大写字母,组件采用大驼峰;
  3. CSS采用普通CSS和styled-component结合来编写(全局采用普通CSS、局部采用styled-component);
  4. 整个项目不再使用class组件,统一使用函数式组件,并且全面拥抱Hooks;
  5. 所有的函数式组件,为了避免不必要的渲染,全部使用memo进行包裹;
  6. 组件内部的状态,使用useState、useReducer;业务数据全部放在redux中管理;
  7. 函数组件内部基本按照如下顺序编写代码:
  • 组件内部state管理;
  • redux的hooks代码;
  • 其他hooks相关代码(比如自定义hooks);
  • 其他逻辑代码;
  • 返回JSX代码;
  1. redux代码规范如下:
  • redux目前我们学习了两种模式,在项目实战中尽量两个都用起来,都需要掌握;
  • 每个模块有自己独立的reducer或者slice,之后合并在一起;
  • redux中会存在共享的状态、从服务器获取到的数据状态;
  1. 网络请求采用axios
  • 对axios进行二次封装;
  • 所有的模块请求会放到一个请求文件中单独管理;
  1. 项目使用AntDesign、MUI(Material UI)
  • 爱彼迎本身的设计风格更多偏向于Material UI,但是课程中也会尽量讲到AntDesign的使用方法;
  • 项目中某些AntDesign、MUI中的组件会被拿过来使用;
  • 但是多部分组件还是自己进行编写、封装、实现;
  1. 其他规范在项目中根据实际情况决定和编写;

创建项目

◼ 创建项目的方式:create-react-app
◼ 项目配置:
 配置项目的icon
 配置项目的标题
 配置jsconfig.json
◼ 通过craco配置别名和less文件:

jsconfig.json

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

项目目录结构划分

在一个React项目中,保持代码规范和结构清晰有助于提高可维护性和可读性。以下是一些新手可以遵循的规范和最佳实践来创建React项目:

项目结构

  1. 目录结构

    • src/: 源代码目录,存放组件、页面、样式等。
    • public/: 存放静态资源,如图片、字体等。
    • assets/: 可存放项目中使用的资源文件,例如图片、字体、图标等。
    • components/: 存放可复用的组件。
    • pages/: 存放页面级组件。
    • styles/: 存放全局样式文件。
    • utils/: 存放通用函数。
    • services/: 存放API调用相关代码。
    • hooks/: 存放自定义Hook。
    • tests/: 存放测试文件。
  2. 组件划分

    • 函数式组件:优先使用函数式组件,配合React Hooks使用。
    • 逻辑与展示分离:在组件内部,将逻辑代码和展示代码分开,便于理解和维护。
  3. 文件命名

    • 文件命名采用驼峰式或帕斯卡命名法(例如:MyComponent.js)。
    • 文件扩展名为.js.jsx,具体视项目的配置而定。
  4. 样式

    • 使用模块化CSS或CSS-in-JS来管理组件的样式,避免样式冲突。
    • 使用命名空间或特定命名规则(如BEM)来规范样式类名。

在这里插入图片描述

别名配置 @

index.js

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

// @ => src:webpack  (采用第二种方法)
// 问题 react脚手架隐藏webpack
// 解决一 npm run reject
// 解决二 craco =>create-react-app config 

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

在这里插入图片描述

安装依赖

npm i @craco/craco@alpha -D

修改配置
创建文件夹craco.config.js

const path = require('path')

const resolve = (pathName) => path.resolve(__dirname, pathName)
module.exports = {
  // less
  // webpack
  webpack: {
    alias: {
      '@': resolve('src'),
      'components': resolve('src/components'),
      'utils': resolve('src/utils'),
    },
  },
}

在修改package.json

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "craco eject"
  },

启动

npm run start

配置less

在这里插入图片描述

安装

npm i craco-less@2.1.0-alpha.0 -D

配置
在这里插入图片描述
craco.config.js

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

CSS样式的重置

  1. 对默认CSS样式进行重置:
  • normalize.css
    安装
npm i normalize.css
  • reset.less

@import "./variables.less";

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

a {
  color: @textColor;
  text-decoration: none;
}


img {
  vertical-align: top;
}

ul, li {
  list-style: none;
}


variables.less定义变量

@textColor: #484848;
@textColorSecondary: #222;


在这里插入图片描述
index.js中配置

import "normalize.css";
import './assets/css/index.less';

全家桶 – Router配置

安装

npm i react-router-dom

index.js 配置

import React, { Suspense } from 'react'
import ReactDOM from 'react-dom/client'
import { HashRouter } from "react-router-dom"

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <Suspense fallback="loading">
      <HashRouter>
        <App />
      </HashRouter>
    </Suspense>
  </React.StrictMode>
)

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

在这里插入图片描述
App.jsx

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

const App = memo(() => {
  return (
    <div className='app'>
      <div className='header'>header</div>
      <div className='page'>
        {useRoutes(routes)}
      </div>
      <div className='footer'>footer</div>
    </div>
  )
})

export default App

全家桶 – Redux状态管理

安装

npm i @reduxjs/toolkit react-redux

开始配置

  1. 创建文件 sotre
    在这里插入图片描述
  2. store/index.js

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

// 两种方式配置 reducer
const store = configureStore({
  reducer: {
  },
})

export default store
  1. 入口 修改index.js
import { Provider } from 'react-redux'
import store from './store'

// 使用 Redux Provider 包裹应用
root.render(
  <React.StrictMode>
    <Suspense fallback="loading">
      <Provider store={store}>
        <HashRouter>
          <App />
        </HashRouter>
      </Provider>
    </Suspense>
  </React.StrictMode>
)
  1. 在 Store 中注册 State Slice
    在这里插入图片描述
    home.js
import { createSlice } from '@reduxjs/toolkit'

const homeSlice = createSlice({
  name: 'home',
  initialState: {
    productList:[]
  },
  reducers: {
    
  }
})
// 注册到store中
export default homeSlice.reducer

如果我们将所有的逻辑代码写到一起,那么当redux变得复杂时代码就难以维护。

  • 接下来,我会对代码进行拆分,将store、reducer、action、constants拆分成一个个文件。
  • 创建store/index.js文件:
  • 创建store/reducer.js文件:
  • 创建store/actionCreators.js文件:
  • 创建store/constants.js文件:

reducer.sj

const initialState = {
  currentPage: 3,
}

function reducer(state = initialState, action) {
  switch (action.type) {
    default:
      return state
  }
}

export default reducer

index.js

import reducer from './reducer'


export default reducer

store/index.js


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

// 两种方式配置 reducer
const store = configureStore({
  reducer: {
    home: homeReducer, // 注册reducer
    entire: entireReducer, // 注册reducer
  },
})

export default store

运行项目
在这里插入图片描述

网络请求 - axios

安装

npm i axios

目录
在这里插入图片描述
配置
request/config.js

export const BASE_URL = 'http://codercba.com'
export const TIMEOUT = 10000

request/index.js


import axios from 'axios'
import { BASE_URL, TIMEOUT } from './config'
// 创建实例
class CRequest {
  constructor(baseURL, timeout) {
    this.instance = axios.create({
      baseURL,
      timeout,
    })
    this.instance.interceptors.response.use(
      (res) => {
        return res.data
      },
      (err) => {
        return err
      }
    )
  }

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

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

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

export default new CRequest(BASE_URL, TIMEOUT)

services/index.js

import hRequest from './request';

export default hRequest

组件中测试

import React, { memo, useEffect } from 'react'
import hRequest from '@/services'
const index = memo(() => {
  // 网络请求
  useEffect(() => {
    hRequest.get({ rul: '/home/highscore' }).then(res => {
      console.log(res);
    })
  },[])
  return (
    <div>Home</div>
  )
})

export default index

以上配置是基础版本,后续会随着项目的深入而继续完善

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mybatis05:复杂查询:(多对一,一对多)

mybatis05&#xff1a;复杂查询&#xff1a;&#xff08;多对一&#xff0c;一对多&#xff09; 文章目录 mybatis05&#xff1a;复杂查询&#xff1a;&#xff08;多对一&#xff0c;一对多&#xff09;前言&#xff1a;多对一 &#xff1a; 关联 &#xff1a; 使用associatio…

三子棋+迷宫

又水了一篇&#xff0c;嘿嘿不废话了&#xff0c;正文开始 文章目录 1.三子棋&#xff08;Tic-Tac-Toe&#xff09;游戏流程解析游戏设计游戏代码实现1. 包含头文件和定义全局变量2. 初始化游戏板3. 打印游戏板4. 玩家行动5. 检查胜利条件6. 主函数下面是完整的C语言代码 2.控…

机器学习——概述总结

总图&#xff1a; 分部1&#xff1a; 分部2&#xff1a; 分部3&#xff1a;

计算机基础知识-第7章-程序的本质(2)——算法与数据结构概论

一、算法数据结构程序 提出这一公式并以此作为其一本专著的书名的瑞士计算机科学家尼克劳斯沃思&#xff08;Niklaus Wirth&#xff09;由于发明了多种影响深远的程序设计语言&#xff0c;并提出结构化程序设计这一革命性概念而获得了1984年的图灵奖。他是至今惟一获此殊荣的瑞…

k8s的ca以及相关证书签发流程

k8s的ca以及相关证书签发流程 1. kube-apiserver相关证书说明2. 生成CA凭证1.1. 生成CA私钥1.2. 生成CA证书 2. 生成kube-apiserver凭证2.1. 生成kube-apiserver私钥2.2. 生成kube-apiserver证书请求2.3. 生成kube-apiserver证书 3. 疑问和思考4. 参考文档 对于网站类的应用&am…

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程 1.1、operator()的引入 现在需要完成这样一个需求&#xff1a;有一个函数每次调用返回的结果不一样。例如&#xff1a;两次调用的返回值都不一样那么就可以达到这种目的 1.1.1、简单点的写法 可以给一个全局的变量&#xff08;静态变量&#xff09;&#xff…

交换机与路由器缓冲区:寻找完美大小

*本文系SDNLAB编译自瞻博网络技术专家兼高级工程总监Sharada Yeluri领英 在路由器和交换机中&#xff0c;缓冲区至关重要&#xff0c;可以防止网络拥塞期间的数据丢失。缓冲区到底要多大&#xff1f;这个问题在学术界和工业界一直备受争议。本文探讨了高端路由器中数据包缓冲的…

书生·浦语大模型全链路开源体系-第3课

书生浦语大模型全链路开源体系-第3课 书生浦语大模型全链路开源体系-第3课相关资源RAG 概述在 InternLM Studio 上部署茴香豆技术助手环境配置配置基础环境下载基础文件下载安装茴香豆 使用茴香豆搭建 RAG 助手修改配置文件 创建知识库运行茴香豆知识助手 在茴香豆 Web 版中创建…

荒野奔驰,在泥泞中体验惊心动魄的冒险

从亚利桑那州的金色沙漠到喀尔巴阡山脉的崇山峻岭&#xff0c;在这片无垠的开放世界中&#xff0c;蕴藏着无尽的宝藏与古老的废墟&#xff0c;等待着勇敢者的发现。《远征&#xff1a;泥泞奔驰游戏》作为Saber Interactive打造的又一越野模拟力作&#xff0c;继《雪地奔驰》之后…

记录一次Ubuntu 22.04桌面版安装向日葵的过程

大概花了近一天的时间安装了WIN11和Ubuntu 22.04双系统&#xff0c;中间Ubuntu安装时出现了好几次失败&#xff0c;后来检查可能是下载的iso文件有问题&#xff0c;重新下载一次&#xff0c;刻录到U盘。安装才算成功。 最后的Ubuntu系统信息如下 接着安装向日葵的时候出错了&a…

模组硬件通用|ESD静电释放注意事项

当我们在进行接插件操作或者电路板调试时&#xff0c;有时会出现接口损坏或者电路板上的某个IC芯片失效的情况&#xff0c;原因可能仅仅是手触摸到了IC芯片&#xff0c;ESD(Electro-Static discharge 静电释放)导致了损坏。模组作为一个集成电路板&#xff0c;内部含有不同型号…

003Node.js创建第一个web服务

如果用PHP来编写后端代码&#xff0c;需要用Apache或者Nginx的服务器,来处理客户的请求响应。对于Node.js时&#xff0c;不仅实现了应用&#xff0c;同时还实现了整个HTTP服务器. 安装 Node Snippets插件&#xff08;编程自带提示&#xff09; console.log(你好nodejs); //表…

Golang 并发安全Map容器实践

Golang原生Map容器并非支持并发安全&#xff0c;在实际使用的时候很容易导致条件竞争并造成未知问题&#xff0c;本文介绍了在Golang中如何安全的并发访问Map容器。原文: Concurrent-Safe Map Container in Go Georg Bommeli Unsplash 当多个程序同时尝试写入同一个map时&#…

【MATLAB源码-第186期】matlab基于MLE算法的8天线阵列DOA估计仿真,对比粗估计、精确估计输出RMSE对比图。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 第一部分&#xff1a;基本概念与系统设置 方向到达估计&#xff08;Direction of Arrival, DOA&#xff09;是信号处理中一项重要的技术&#xff0c;主要用于确定信号的到达方向。这种技术在雷达、无线通信和声纳等领域中有…

PandasAI的应用与实战解析(一):环境安装、运行demo

文章目录 1.源码包下载、明确依赖版本2.安装python依赖3.运行demo 本博客源码仓库地址&#xff1a;gitlab&#xff0c;本篇博客对应01分支python版本为3.10.x 什么是PandasAI&#xff1f;一句话总结的话&#xff0c;PandasAI就是一个结合了Pandas和AI的开源工具&#xff0c;更…

代码随想录阅读笔记-回溯【组合总和II】

题目 给定一个数组 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。 说明&#xff1a; 所有数字&#xff08;包括目标数&#xff09;都是正整数。解集不能包含重复的组…

Pytest精通指南(06)Fixture scope作用域详解

文章目录 前言Scope 作用域写在测试用例函数文件写在conftest.py文件作用域总结验证默认作用域验证执行顺序遵循验证类中的fixture作用域验证重名fixture作用域 前言 从前文中&#xff0c;我们已经知道固件&#xff08;fixture&#xff09;的概念、原理、作用域&#xff0c;并且…

TMS320F280049 EPWM模块--PC子模块(5)

下图是PC子模块和其他子模块的联系图。可以看出&#xff0c;PC接收DB的输出&#xff0c;然后处理后给到TZ。 下图是PC子模块的内部框图。可以看到&#xff1a; 1&#xff09;PC子模块功能可以被bypass&#xff1b; 2&#xff09;one shot和divider的时钟是epwm时钟的8分频&am…

秋招数据库学习2(20240408-20240412共10道)

由于感觉数据库难度可能暂时面试用不到&#xff0c;就先不刷啦 20240408 1.从不订购的客户 SELECT Name AS Customers FROM Customers C LEFT JOIN Orders O ON C.Id O.CustomerId WHERE CustomerId is nullselect customers.name as Customers from Customers wher…

购物车实现

目录 1.购物车常见的实现方式 2.购物车数据结构介绍 3.实例分析 1.controller层 2.service层 1.购物车常见的实现方式 方式一&#xff1a;存储到数据库 性能存在瓶颈方式二&#xff1a;前端本地存储 localstorage在浏览器中存储 key/value 对&#xff0c;没有过期时间。s…