# 一、creat-react-app
creat-react-app 是facebook 官方推出的一款react 的脚手架
尽量升级到最新版
# 1.1 快速入手
# 全局安装脚手架
npm i -g create-react-app
# 检验版本成功与否
create-react-app --version
2
3
# 创建初始化项目
# 切换到指定目录
npx create-react-app my-app
2
# 启动项目
npm start
# 运行成功后结果如下,控制台也无报错信息
2
# 1.2 文件目录介绍
.
├── build/ : 存放项目被webpack处理后生成的文件;
├── node_modules/ : 存放 npm 安装的工具包 或 模块;
├── public/ : 静态资源,该目录下的文件不会被webpack处理,它们会被拷贝到 build/ 文件夹下;
└── src/ : 项目的源代码及资源;
└──components/ :组件文件夹
2
3
4
5
6
注意:
- 组件中根节点只能有一个,如果不想新增DOM 节点可以使用空标签
<></>
或者<Fragment></Fragment>
来包裹 - 如果引用静态资源,常用的有三种方式:
- 将文件置于
public
文件夹下,可以直接引用文件名使用 - 直接使用
require
来引用,<img src={ require('../1.jpg' ) } />
- 先使用
import Img from '../1.jpg'
引入,再使用<img src={ Img } />
- 将文件置于
# 二、组件传值
组件传值包括Redux 这一块我在另一篇文章中有做详细总结
# 三、数据请求
# 1.1 json-server
json-server
是一个模拟数据的一个插件,这个插件可以很方便的将json 格式文件模拟成数据接口,模拟的接口遵循‘RESTful API接口规范’ ,使用这个插件能很方便我们调试
1. 全局安装
npm i -g json-server
2. 创建模拟数据
{
"list": [
{"id": 1,"name": "张三"},
{"id": 2,"name": "李四"},
...
]
}
2
3
4
5
6
7
3. 启动插件
json-server ./db/data.json --port 4000
这样就能将插件启动起来了,这时候按RESTful API 的接口规范
访问本地服务4000端口就能请求到数据了
# 1.2 传统ajax
前端程序员常说的Ajax是 Asynchronous JavaScript and XML
的缩写,意思是异步网络请求。区别于传统web开发中采用的同步方式。Ajax带来的最大影响就是页面可以无刷新的请求数据。
在现代浏览器上实现一个Ajax请求是非常容易的
var request = new XMLHttpRequest(); // 创建XMLHttpRequest对象
//ajax是异步的,设置回调函数
request.onreadystatechange = function () { // 状态发生变化时,函数被回调
if (request.readyState === 4) { // 成功完成
// 判断响应状态码
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
return success(request.responseText);
} else {
// 失败,根据响应码判断失败原因:
return fail(request.status);
}
} else {
// HTTP请求还在继续...
}
}
// 发送请求:
request.open('GET', '/api/categories');
request.setRequestHeader("Content-Type", "application/json") //设置请求头
request.send();//到这一步,请求才正式发出
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1.3 axios
axios 是非常常用的一个第三方插件,axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范
axios.get('http://127.0.0.1:4000/list').then((res) => {
if (res.status == 200) {
console.log(res.data)
}
})
2
3
4
5
# 1.4 fetch
fetch是前端发展的一种新技术产物。Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
fetch代表着更先进的技术方向,但是目前兼容性不是很好,在项目中使用的时候得慎重
fetch('http://example.com/movies.json')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
2
3
4
5
6
7
# 四、React 中解决跨域
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
相似策略/ SOP(Same origin policy)是一种约定,由Netscape公司1995年发布,它是浏览器最核心也最基本的安全功能,如果可以了类似策略,浏览器很容易受到XSS ,CSFR等攻击。所谓同源是指“协议+域名+端口”三者相同,甚至两个不同的域名指向同一个IP地址,也非同源。
只要试图请求非同源的资源就会产生跨域,如下所示:
# 1.1 正向代理
开发环境使用较多,一个位于客户端和目标服务器之间的代理服务器,为了获取到目标服务器的内容,客户端向代理服务器发送一个请求,代理服务器帮助我们去目标服务器里面获取数据并返回给我们
快速使用
先找到node_modules\react-scripts\config\webpackDevServer.config.js
文件并打开
找到proxy配置项,并添加如下配置
proxy: {
"/api": {
target: 'http://www.weather.com.cn/data/cityinfo',
changeOrigin: true,
"pathRewrite": {
"^/api": "/"
}
}
}
2
3
4
5
6
7
8
9
中国天气网:香港地区天气数据
经过这么一配置,我们再进行请求/api
就不会跨域了
# 1.2 反向代理
上线环境使用较多,可以通过代理服务起来接收网络上的请求拦截,然后将这个请求转发给内部的网络服务器上,并且把这个服务器得到的数据返回给请求的客户端,这个时候代理服务器对外的表现就是一个反向代理,需要后端配合
# 五、路由
# 1.1 基本介绍
根据url的不同来切换对应的组件,实现spa(单页面应用),在页面切换的时候不会刷新,更加接近原生体验
开发中常用的路由插件有两种:
- react-router:值提供了一些核心的APi,功能相对更精简
- react-router-dom:在以上基础上增加了更多的功能选项
常用的路由切换模式分为两种:
- HashRouter:带#号,刷新的时候页面不会丢失
- BrowserRouter:历史记录模式,没有#号,他是通过历史记录api来进行路由切换的,切换会丢失,但是本地模式不会
# 1.2 react-router-dom
1. 装包
npm i react-router-dom -S
2. 导入组件
import { BrowserRouter, HashRouter,Redirect, Switch, Route, Link } from 'react-router-dom'
上面几个组件是常用的
BrowserRouter:作为根组件时,表明是历史模式路由
HashRouter:作为根组件时,表明是哈希模式路由
Route:路由设置,有两个必备属性和一个重要属性
- path:匹配的路由规则
- component:将要渲染的组件
- exact:启用代表精准匹配
Redirect:重定向设置,同样有两个必备属性和一个重要属性
- from:表示触发的路由规则
- to:表示重定向的目标路由
- exact:启用代表精准匹配
Link/NavLink:表示跳转设置,有一个必备属性
- to:代表着将要跳转的路由,类似a 标签的href 属性
Switch:作为根组件包裹,防止多次渲染
# 1.3 高阶组件
高阶组件:也称为HOC,参数是一个组件,同时返回的也是一个组件,就是让不是路由切换的组件也具有路由切换的属性,这三个属性是(location, match, history)
import { withRouter } from 'react-router-dom'
...
export dafault withRouter(App)
2
3
# 1.4 路由传参
# params 传参方式:
- 需要在路由规则中设置传递的接收参数 :xxx
- 发送参数,直接在跳转路径后进行明文编写
- 接受
props.match.params.参数名
优势:刷新地址,参数依然存在
缺点:只能以字符串形式传递参数,参数过长时url会变得很难看
# query 传参方式:
- 不需要再路由中进行传递参数的配置
- 直接发送数据
- 使用
this.props.location.query.参数名
接收
<NavLink to={{pathname:'/user',query:{name:'zs'}}}>点我发送数据</NavLink>
componentDidMount(){
console.log(this.props.location.query)
}
// {name:'zs'}
2
3
4
# 六、Hook的使用
Hook 是react 16.7 新增的一个特性,主要是用来让无状态组件可以使用状态,在react 开发中状态的管理是必不可少的,以前为了进行状态管理,需要使用class 类组件或者redux 等来管理
# 1.1 传统class 组件方式
...
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return (
<div>
</div>
)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.2 使用Hook
react 中有一个组件useState
可以在函数组件中实现状态管理
useState是来定义一个状态的,他与类组件的状态不同,函数组件的状态可以是对象也可以是基础类型数据
import React, { useState } from 'react'
export default function App() {
const [val, setVal] = useState('状态信息')
return (
<div>
当前的数据:{ val }
<button onClick={ ()=>{ setVal('更改后的状态信息') } }>更改状态数据</button>
</div>
)
}
2
3
4
5
6
7
8
9
10
11
12
13
useState 返回的是一个数组,第一个参数是当前状态的值,第二个参数表明用于更改状态的函数,类似setState
如果有多个状态怎么办?
声明对象类型的状态
const [val, setVal] = useState({ val1: 'val1', val2: 'val2' }) 当前的数据:{ val.val1 } × 不能被修改
1
2
3
4
5
6
7多次声明(推荐使用)
const [val1, setVal1] = useState('参数1') const [val2, setVal2] = useState('参数2') 当前的数据:{ val1 } √ 可以修改
1
2
3
4
5
# 1.3 Redux
在另一篇文章详细说明React中的数据传值总结