# React基础学习 **Repository Path**: wb04307201/react-class ## Basic Information - **Project Name**: React基础学习 - **Description**: React基础学习——项目初始化,项目结构,教程,常用依赖库等 - **Primary Language**: JavaScript - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-01-04 - **Last Updated**: 2023-05-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # React基础学习 * ### [1.初始化项目](#1) * #### [1.1 环境](#1.1) * #### [1.2 初始化](#1.2) * #### [1.3 运行](#1.3) * ### [2.项目结构](#2) * #### [2.1 整体](#2.1) * #### [2.2 package.json](#2.2) * ### [3.边做边学](#3) * ### [4.常用依赖库](#4) * #### [4.1 cnpm镜像仓库](#4.1) * #### [4.2 路由](#4.2) * #### [4.3 请求和代理](#4.3) * [4.3.1 axios](#4.3.1) * [4.3.2 代理](#4.3.2) * [4.3.3 拦截器](#4.3.3) * #### [4.4 UI组件库](#4.4) ##

1.初始化项目

###

1.1 环境

Node.js 是一个免费的、开源的、跨平台的 JavaScript 运行时环境,允许开发人员在浏览器之外编写命令行工具和服务器端脚本. 安装NodeJS [下载地址](https://nodejs.org/zh-cn/) 1. npm NodeJS的包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准 2. yarn 是一个由 Facebook 贡献的 Javascript 包管理器 3. npx 则可以快捷的运用包中的命令行工具和其他可执行文件,让项目内部安装的模块用起来更方便 ###

1.2 初始化

打开终端 执行 npx create-react-app react-class 等待执行完成,如下图 ![img.png](img.png) 使用开发工具(VS Code,WebStorm等)打开项目 *PS:* 如果是从git上下载的项目,需要在项目目录下执行npm install或者yarn install安装依赖包 ###

1.3 运行

打开命令提示符执行命令npm run start启动项目 ![img_1.png](img_1.png) ![img_2.png](img_2.png) ##

2.项目结构

###

2.1 整体

```text 初始项目结构如下: ┌── public // 公共资源文件 │ ├── favicon.ico // 是浏览器tab上图标,也是这个项目的一个标志,也可以说是代表一个公司的标志。可以替换。 │ ├── index.html // 主文件 │ ├── manifest.json // 编译配置文件 │ └── ... // 其他 ├── node_modules // 项目依赖包文件夹 ├── src // 我们的项目的源码编写文件(里面的文件可根据喜好,随意更改) │ ├── App.css // App样式文件 │ ├── App.js // 入口组件,其他组件会被插入此组件中,此组件通过index.js再插入 index.html 文件里,形成单页面应用; │ ├── App.test.js // 测试文件 │ ├── index.css // index样式文件 │ ├── Home.js // 存放的是这个项目的核心内容,也就是我们的主要工作区域。其中,index.js文件是和index.html进行关联的文件的唯一接口,类似vue里面的main.js │ ├── reportWebVitals.js // web-vitals 通过把index.js文件的最后一行改为reportWebVitals(console.warn)可以在控制台中看到指标输出 │ ├── setupTests.js // 测试框架初始化 │ └── ... // 其他 ├── package-lock.json // 锁定依赖版本,使用npm install后生成 ├── yarn.lock // 锁定依赖版本,使用yarn install后生成 ├── package.json // 项目依赖包配置文件(node配置文件) ├── .gitignore // 用于排除git提交时的部分文件 └── README.md // 项目说明文档 ``` ###

2.2 package.json

##### 1.概述 每个项目的根目录下面都有一个package.json文件,定义了这个项目所需要各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据) ```json { "name": "react-class", "version": "0.1.0" } ``` ##### 2.scripts script指定了运行脚本命令的npm命令行缩写,比如start指定了npm run start 时所需要执行的命令 ```json { "scripts": { "start": "react-scripts start", //启动项目 "build": "react-scripts build", //构建项目(生成编译后的静态资源) "test": "react-scripts test", //执行测试 "eject": "react-scripts eject" //将所有依赖复制进项目中(过程不可逆,因此不要随便用这个命令) } } ``` ##### 3.dependencies、devDependencies dependencies字段指定了项目运行所依赖的模块,devDependencies指定项目开发所需要的模块 ```json { "dependencies": { "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.0" } } ``` ##

3.边做边学

[参照教程完成井字棋](https://react.docschina.org/learn/tutorial-tic-tac-toe) ![img_3.png](img_3.png) *PS:* 教程中的函数组件即为Hook,是React 16.8 的新增特性,[详细内容请点击此处查看](https://react.docschina.org/docs/hooks-intro.html) ![img_4.png](img_4.png) ? 试试将井字棋修改为五子棋和黑白棋 五子棋 ![img_11.png](img_11.png) 黑白棋 ![img_12.png](img_12.png) ##

4.常用依赖库

###

4.1 cnpm镜像仓库

安装NodeJS后可以使用NPM管理项目使用的依赖 但是npm默认的仓库地址为:http://registry.npmjs.org 服务器在国外,所以有时候难免出现访问过慢,甚至无法访问的情况 我们一般需要使用公司的私库或者国内的npm镜像库,比如阿里的cnpm等 使用方法: 1. 直接安装cnpm 在终端中执行npm install -g cnpm --registry=https://registry.npm.taobao.org 以后安装直接采用cpm替代npm 例如原生npm命令为:npm install uniq --save,cnpm命令为:cnpm install uniq --save 2. 替换npm仓库地址为淘宝镜像地址 在终端中执行npm config set registry https://registry.npm.taobao.org 以后安装时,依然用npm命令,但是实际是从淘宝国内服务器下载的 *PS:* 1. 查看当前npm仓库地址命令:npm config get registry 2. 查看yarn仓库 yarn config get registry 修改yarn仓库 yarn config set registry https://registry.npm.taobao.org 3. 安装nrm(npm registry manager)工具进行npm的镜像源管理 命令 npm install -g nrm 安装nrm *ps:目前nrm和open版本存在兼容性异常,需要指定open版本为8.4.2,命令为npm install -g nrm open@8.4.2* 命令nrm ls 查看自带配置,*为当前的配置 ![img_5.png](img_5.png) 命令 nrm use taobao 切换当前源地址 命令 nrm del taobao 删除源地址 命令 nrm add ??? https://????.???/ 添加源地址 命令 nrm test npm 测试访问时间 ###

4.2 路由

什么是路由? 1.一个路由就是一个映射关系(key:value) 2.key为路径, value可能是function或component react-router-dom 一个路由插件依赖库 官方从5开始就已经放弃了原有的 react-router 库,统一命名为 react-router-dom 1. 安装react-router-dom依赖库 命令 npm install react-router-dom --save 或者 命令 yarn add react-router-dom 2. 引入实现路由所需的组件,以及页面组件 ```javascript import { BrowserRouter, Routes, Route } from "react-router-dom"; import { Home } from "./pages/Home/Home"; import { Reversi } from "./pages/Reversi/Reversi"; function App() { return ( } /> } /> ); } ``` 3. 1. 路由跳转 Link 组件 ```javascript import { Link } from "react-router-dom"; 井字棋 ``` 3. 2. 路由跳转 NavLink 组件 ```javascript import { NavLink } from "react-router-dom"; ({ color: isActive ? "red" : "#fff" })}> Click here ``` 3. 3. 路由跳转 编程式跳转 ```javascript import { useNavigate } from 'react-router-dom'; ``` ? 试着完成一个可以相互跳转的页面吧 ![img_6.png](img_6.png) ###

4.3 请求

####

4.3.1 axios

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。 在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。 [官方文档](https://axios-http.com/zh/) 1. 安装axios依赖库 命令 npm install axios --save 或者 命令 yarn add axios 2. 发起一个请求 ```javascript //get请求 axios.get("https://v1.hitokoto.cn/") .then(function(response){ console.log(response); setHitokoto(response.data.hitokoto) }) .catch(function(error){ console.log(error); }) //post请求 axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); //并发请求 function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } Promise.all([getUserAccount(), getUserPermissions()]) .then(function (results) { const acct = results[0]; const perm = results[1]; }); ``` ? 试试使用get请求获取数据吧 ![img_7.png](img_7.png) ####

4.3.2 代理

把get请求的地址换成http://open.iciba.com/dsapi/?date= 这时会发生跨域异常 ![img_8.png](img_8.png) 我们需要借助代理功能解决这个问题 react可以直接在package.json中配置proxy ```json "proxy":"http://open.iciba.com" ``` 并修改请求地址为 ```javascript axios.get("/dsapi/?date=") ``` *PS:* 新版本的proxy匹配字符串格式进行设置 老版本匹配对象进行设置,如下 ```json "proxy": { "/api/**": { "target": "http://172.16.136.249:8080", "changeOrigin": true } } ``` 重启服务可以正常进行请求 ![img_9.png](img_9.png) *PS:* 可以在setupProxy.js文件中使用http-proxy-middleware依赖库进行更详细的路由设置,默认已集成在react脚手架中 ```javascript const proxy = require('http-proxy-middleware')//引入http-proxy-middleware,react脚手架已经安装 module.exports = function(app){ app.use( proxy.createProxyMiddleware('/api',{ //遇见/api前缀的请求,就会触发该代理配置 target:'http://localhost:5000', //请求转发给谁 changeOrigin:true,//控制服务器收到的请求头中Host的值 pathRewrite:{'^/api':''} //重写请求路径,下面有示例解释 }), proxy.createProxyMiddleware('/api2',{ target:'http://localhost:5001', changeOrigin:true, pathRewrite:{'^/api2':''} }), ) } ``` [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) ####

4.3.3 拦截器

查看上一步console.log(response)打印出的结果 ```json { "data": { "sid": "4734", "tts": "https://staticedu-wps.cache.iciba.com/audio/245a517f64d7533c73ac7cc8c9c77f67.mp3", "content": "Pursue excellence, and success will follow.", "note": "追求卓越,成功随之而来。", "love": "0", "translation": "新版每日一句", "picture": "https://staticedu-wps.cache.iciba.com/image/9148e6efdda98b80cf5f3b9e5dee2baf.jpg", "picture2": "https://staticedu-wps.cache.iciba.com/image/7eec7cadfcc61cbebc851e1d4ef748ad.jpg", "caption": "词霸每日一句", "dateline": "2023-01-10", "s_pv": "0", "sp_pv": "0", "fenxiang_img": "https://staticedu-wps.cache.iciba.com/image/e49c68a00fef1400269381fb4f37b439.png", "picture3": "https://staticedu-wps.cache.iciba.com/image/9316079244fd7e592b590de5a80d3b09.jpg", "picture4": "https://staticedu-wps.cache.iciba.com/image/423ce0d40b1d3ecbac0ab9bd39779985.jpg", "tags": [] }, "status": 200, "statusText": "OK", "headers": { "access-control-allow-headers": "*", "access-control-allow-methods": "*", "access-control-allow-origin": "*", "connection": "close", "content-encoding": "gzip", "content-type": "text/html; charset=utf-8;", "date": "Tue, 10 Jan 2023 02:57:10 GMT", "server": "nginx", "transfer-encoding": "chunked", "vary": "Accept-Encoding", "x-powered-by": "PHP/5.5.24" }, "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "adapter": [ "xhr", "http" ], "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, "headers": { "Accept": "application/json, text/plain, */*" }, "method": "get", "url": "/dsapi/?date=" }, "request": {} } ``` 包括部分冗余信息,这里可以使用axios的拦截器进行处理 在src下创建utils/http.js ```javascript import axios from 'axios' const http = axios.create({ // baseURL: 'http://open.iciba.com', timeout: 5000, }) // 添加请求拦截器 http.interceptors.request.use(config => { // 在发送请求之前做些什么 return config; }, (error) => { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 http.interceptors.response.use(response => { // 对响应数据做点什么 return response.data; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); export default http; ``` 并修改请求部分 ```javascript http.get("/dsapi/?date=") .then(function(response){ console.log(response); setText(response.content); }) .catch(function(error){ console.log(error); }) ``` 查看console.log(response)的结果 ```json { "sid": "4734", "tts": "https://staticedu-wps.cache.iciba.com/audio/245a517f64d7533c73ac7cc8c9c77f67.mp3", "content": "Pursue excellence, and success will follow.", "note": "追求卓越,成功随之而来。", "love": "0", "translation": "新版每日一句", "picture": "https://staticedu-wps.cache.iciba.com/image/9148e6efdda98b80cf5f3b9e5dee2baf.jpg", "picture2": "https://staticedu-wps.cache.iciba.com/image/7eec7cadfcc61cbebc851e1d4ef748ad.jpg", "caption": "词霸每日一句", "dateline": "2023-01-10", "s_pv": "0", "sp_pv": "0", "fenxiang_img": "https://staticedu-wps.cache.iciba.com/image/e49c68a00fef1400269381fb4f37b439.png", "picture3": "https://staticedu-wps.cache.iciba.com/image/9316079244fd7e592b590de5a80d3b09.jpg", "picture4": "https://staticedu-wps.cache.iciba.com/image/423ce0d40b1d3ecbac0ab9bd39779985.jpg", "tags": [] } ``` *PS:* 拦截器可以用于多种场景,比如异常处理,用户失效处理,请求头增加token等 ###

4.4 UI组件库

UI组件库提供已封装好的组件,以antd为例安装组件库并使用 [Ant Design](https://ant.design/index-cn) 1. 安装antd 命令 npm install antd --save 或者 命令 yarn add antd 2. 安装图标 命令 npm install @ant-design/icons --save 或者 命令 yarn add @ant-design/icons 3. 参照[快速上手](https://ant.design/docs/react/getting-started-cn)完成组件的使用 ? 试着使用各种组件完成页面吧 ![img_10.png](img_10.png)