# 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
等待执行完成,如下图

使用开发工具(VS Code,WebStorm等)打开项目
*PS:*
如果是从git上下载的项目,需要在项目目录下执行npm install或者yarn install安装依赖包
### 1.3 运行
打开命令提示符执行命令npm run start启动项目


## 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)

*PS:*
教程中的函数组件即为Hook,是React 16.8 的新增特性,[详细内容请点击此处查看](https://react.docschina.org/docs/hooks-intro.html)

? 试试将井字棋修改为五子棋和黑白棋
五子棋

黑白棋

## 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 查看自带配置,*为当前的配置

命令 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';
```
? 试着完成一个可以相互跳转的页面吧

### 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请求获取数据吧

#### 4.3.2 代理
把get请求的地址换成http://open.iciba.com/dsapi/?date=
这时会发生跨域异常

我们需要借助代理功能解决这个问题
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
}
}
```
重启服务可以正常进行请求

*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)完成组件的使用
? 试着使用各种组件完成页面吧
