# h5-2103-react
**Repository Path**: htmhl/h5-2103-react
## Basic Information
- **Project Name**: h5-2103-react
- **Description**: react框架
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-07-12
- **Last Updated**: 2021-07-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# React
> https://reactjs.org/
用于构建用户界面的 JavaScript 库
## create-react-app
脚手架,用于构建 react 项目的基本结构
```bash
$ npx create-react-app <项目名称>
# 或
$ yarn create react-app <项目名称>
```
创建后的项目中主要三个包:
- react:核心包
- react-dom:浏览器中DOM渲染时使用到的包
- react-scripts:封装了 webpack 的配置
`npm scripts`:
- start:启动开发环境任务
- build:构建生产环境任务
- test:测试
- eject:弹出 webpack 的配置到项目本地
## JSX
JSX,是一个 JavaScript 的语法扩展。我们建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模板语言,但它具有 JavaScript 的全部功能。
如:
```jsx
const element =
Hello, world!
```
JSX 实际上是语法糖,JSX 也可以用于其它的技术栈中,如 vue,原生JS开发,配合 babel 插件进行转译即可。
在 JSX 中要拼接 JS 表达式的内容,使用 `{}` 语法:
```jsx
const element = function(title) {
return Hello { title }!!!
}
```
React DOM 在渲染所有输入内容之前,(使用` {}` 插入JS表达式)默认会进行转义,以防止 XSS(跨站脚本攻击)攻击。
也可以不进行转义,使用如下类似的代码片段:
```jsx
```
JSX 仅仅只是 `React.createElement(component, props, ...children)` 函数的语法糖。
JSX 本质上是语法糖,使用 babel 可以将 JSX 转译为 `React.createElement()` 的调用:
```jsx
```
经过 Babel 转义:
```js
React.createElement(
'div',
{ className: 'container' },
React.createElement(
'a',
{href: 'xxxx', target: '_blank'},
'链接'
),
React.createElement(
'ul',
null,
React.createElement(
'li',
{ className: 'active' },
'1'
),
React.createElement(
'li',
null,
'2'
)
)
)
```
createElement() 调用后,返回类似如下的对象:
```js
{
tag: 'div',
props: {className: 'container'},
children: [
{
tag: 'a',
props: {href: 'xxxx', target: '_blank'},
children: ['链接']
},
{
tag: 'ul',
props: {},
children: [
{
tag: 'li',
props: {className: 'active', key: 1},
children: ['1']
},
{
tag: 'li',
props: {key: 2},
children: ['2']
}
]
}
]
}
```
## 组件
### 函数组件
```jsx
const Element = props => (
Hello { props.title }!!!
)
```
- 组件名首字母必须大写
- 使用 `<组件名 />` 结构渲染组件
- props 是一个对象,是组件接收到的属性
- JSX 必须有一个根元素(即使用单个根节点包裹布局结构内容)
- 函数组件中没有 this(即 this 的值为 undefined)
### class 组件
```jsx
class Element extends React.Component {
render() {
return (
Hello { this.props.title }!!!
)
}
}
```
- 继承自 React.Component 父组件
- 必须实现 render 函数,在函数体内部返回 React 元素
- 可以在方法中调用 `this.props` 获取组件接收到的属性
## React.Fragment
包裹的 React 元素渲染为 DOM 树时,`` 组件不会渲染到 DOM 树中。
可以简写为 `<>>`
## 组件通信
### 父子
- 父传子:props,利用属性传递数据
- 子传父:利用属性,在父组件中使用子组件时,传递一个函数给子组件,子组件需要向父组件传递数据时,调用到属性中接收到的函数并传递函数参数即可(类似事件)
### 跨层级跨组件
- 转换为父子组件通信
- Context
- flux、redux、mobx......
## props
属性,是组件从父级所接收到的数据。
props 应该是只读的(即不能在组件中修改接收到的属性值)---- 单向数据流,如果需要修改数据,考虑使用 state。
prop-types 包:为 React 组件的属性(props)提供运行时类型检测。
(静态类型检测:TypeScript、Flow)
## state
状态,组件私有使用到的数据,可实现修改(不能直接修改,而是需要调用 setState() 方法来修改)
关于 setState() 修改状态数据时应该知道的三件事:
- 不能直接修改 state(直接修改 state 不会触发视图响应式渲染)。构造函数是唯一可以给 `this.state` 赋值的地方
- state 的更新可能是异步的。
- state 的更新会被合并。
## Refs
Refs 提供了一种方式,允许我们访问 DOM 节点或在 render 方法中创建的 React 元素
- 字符串 ref:不建议使用它
- React.createRef(),可使用创建的 Ref 对象的 current 属性获取关联的 DOM 对象或组件实例
## Context
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
Context 是在全局范围内共享组件要使用的数据。
Context 中通常保存如 地区偏好,UI 主题,语言环境,用户登录状态等
### API
- React.createContext() :用于创建 Context 对象
- Context.Provider:生产者组件,用于向 Context 中保存数据
- Context.Consumer:消费者组件,用于从 Context 中获取数据
- Class.contextType:设置使用到的 Context 对象,就可以不使用 Consumer 组件去获取保存的值
## 生命周期
class 组件中的生命周期钩子函数
### 挂载
- **constructor()**:初始化 state、绑定事件处理程序的 this
- **render()**: 组件视图渲染
- **componentDidMount()**:会在组件挂载后(插入 DOM 树中)立即调用,组件加载需要请求数据,则在该方法中发送网络请求
componentWillMount():组件即将挂载时调用,已过时,UNSAFE_componentWillMount()
### 更新
- shouldComponentUpdate():通常在性能优化的时候使用
- **render()**: 组件视图渲染
- **componentDidUpdate()**:更新后立即调用
### 销毁
- **componentWillUnmount()**:销毁前调用
## 高阶组件
HOC(Higher Order Component)
**高阶组件是参数为组件,返回值为新组件的函数。**
高阶组件本质上就是一个函数,该函数传递组件作为参数,返回新的组件。
设计模式 ---- 装饰者模式
## Hooks
*Hook* 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
即使用 hook 在函数组件中也能够使用类似 class 组件中的特性。
hooks 函数统一以 `use` 作为前缀。
### State Hook
在函数组件中可以使用该 hook 创建类似于 class 组件中的 state
```js
const [state, setState] = useState(initialValue)
```
- useState() 返回的是数组,数组第一个元素为状态,第二个元素为修改状态的函数,initialValue 为状态初始值
# Redux
[文档](https://cn.redux.js.org/)
Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。
Redux 是一个小型的独立 JS 库,redux 与 react 没有任何的关系,Redux 除了和 React 一起用外,还支持其它界面库。
要在 react 中使用 redux,需要安装绑定库:react-redux
## 概念
- **store**:仓库,用于集中式管理 redux 中的状态
- **state**:需要共享管理的状态数据
- **action**:描述发生了什么,是一个普通对象,通常具有 type(动作的类型) 与 payload(动作所携带的有效载荷) 属性,如:
```js
{
type: 'ADD_TO_CART',
payload: {
id: 1,
title: '标题',
price: 9.9,
amount: 1,
checked: false
}
}
```
- **action creator**:函数,用于创建并返回 action 对象
- **reducer**:纯函数,主要用于同步更新状态。该函数会传递 state 与 action 作为参数,返回新的 state 值。reducer 函数是唯一能够更新 state 状态的地方。
**纯函数**:一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数
```html
Reducer 必需符合以下规则:
1. 仅使用 state 和 action 参数计算新的状态值
2. 禁止直接修改 state。必须通过复制现有的 state 并对复制的值进行更改的方式来做 不可变更新(immutable updates)。
3. 禁止任何异步逻辑、依赖随机值或导致其他“副作用”的代码
```
- **dispatch**:函数,传递 action 作为参数,在函数体内部调用 reducer(state, action) 实现状态更新,并执行一些其它注册的监听任务(如响应式渲染刷新页面)。
## 使用
### 安装
```bash
$ npm i redux
# 或
$ yarn add redux
```
### 创建目录
store 目录用于保存所创建 store 对象相关
reducers 目录用于保存同步更新状态的 reducer 函数相关
actions 目录用于保存 action 对象(action creator创建)相关
#### reducer
```js
const initialState = {
}
export default (state = initialState, { type, payload }) => {
switch (type) {
case typeName:
return { ...state, ...payload }
default:
return state
}
}
```
如果应用中有多种类别的状态数据需要管理,可定义不同的 reducer 函数来处理,最后将各独立的 reducer 合并为一个根 reducer 即可:
```js
import { combineReducers } from 'redux'
import todosReducer from './todos'
import usersReducer from './users'
export default combineReducers({
todos: todosReducer,
users: usersReducer
})
```
#### store
```js
import { createStore } from 'redux'
import rootReducer from '../reducers'
const store = createStore(rootReducer)
export default store
```
#### action creator
```js
import { ADD_TODO_ITEM } from "./constants";
export const addActionCreator = title => ({
type: ADD_TODO_ITEM,
payload: {
id: Math.random(),
title,
completed: false
}
})
```
### 安装 react-redux
```bash
$ npm i react-redux
```
### 保存 redux 的 store
```js
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import store from './store'
import App from './App'
import 'bulma/css/bulma.min.css'
render(
,
document.getElementById('root')
)
```
利用 `react-redux` 库中提供的 `Provider` 组件,缓存 store
### 在组件中连接 store
```js
import { connect } from 'react-redux'
// 函数,用于将 store 中的状态数据映射到组件中
// 函数返回值是一个对象,该对象会被合并到组件的 props 中
const mapStateToProps = state => ({
todos: state.todos.todos
})
// 函数,用于 dispatch (触发) action 调用 reducer 更新状态
const mapDispatchToProps = null
// connect() 调用后返回一个函数,该函数为 HOC
const hoc = connect(mapStateToProps, mapDispatchToProps)
export default hoc(TodoList)
```
```js
const mapStateToProps = null
// 函数的返回值是一个对象,会被合并到组件的 props 中
const mapDispatchToProps = dispatch => ({
toggle: id => dispatch(toggleActionCreator(id)),
remove: id => dispatch(removeActionCreator(id))
})
export default connect(mapStateToProps, mapDispatchToProps)(TodoItem)
```
## react-redux
[文档](https://react-redux.js.org/)
### API
**Provider 组件**:
使得所有嵌套在内部的后代组件都可以访问到保存在 Provider 中的 redux 中 store内容,使用 `store` 属性去缓存 redux 的 store 对象。
**connect() 方法:**
使用 connect() 方法来连接 react 组件与 redux 的 store
```js
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
```
- mapStateToProps,函数,传递 state 参数,返回一个对象,主要用于处理 redux 的 store 中的 state。任何时间 store 中的 state 修改了,都会重新计算返回值。返回值(对象)会被合并到组件的 props 中。
- `mapDispatchToProps`,函数,传递 dispatch 参数,返回一个对象,主要用于处理 redux 中 store 的 dispatch。通常返回的对象中包含的就是一个个的方法,各方法体内部实现 `dispatch(action)` 操作,返回的对象会被合并到组件的 props 中
# React Router
[官网](https://reactrouter.com/)
前端路由模式:
- hash
- history
包:
- react-router:核心包
- **react-router-dom:浏览器端**
- react-router-native:原生应用开发,react native 可使用
- react-router-config:静态路由配置相关
## 使用
### 安装
```bash
$ npm i react-router-dom
```
### 组件使用
- HashRouter:创建 hash 路由模式
- BrowserRouter:history 路由模式
- Route:配置静态路由,访问 path 路径时渲染对应的 component 组件
```jsx
{children}
```
- path:URL 路径
- component:待渲染的组件
- render:渲染函数,可用于复杂结构的渲染,component 与 render 不能同时出现,如果同时出现,会忽略 render 的渲染
- children:类似于 render 实现复杂结构的渲染,是 react 元素结构
- Link:导航链接
- Switch:选择
# UI 组件库
[antd](https://ant.design/index-cn)
`antd` 是基于 Ant Design 设计体系的 React UI 组件库
## 使用
### 安装
```bash
$ npm i antd
# 或
$ yarn add antd
```
### 使用组件
```jsx
import 'antd/dist/antd.css'
import { Button } from 'antd'
render() {
return
}
```
默认支持按需引入组件
### 高级配置
安装 craco 包:
```bash
$ npm i @craco/craco -D
```
修改 package.json 文件中的 npm scripts:
```json
{
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
}
```
创建 craco.config.js 文件(项目根目录下):
```js
module.exports = {
// ......
}
```
引入 craco-less 以添加 less 编译及自定义主题功能:
```bash
$ npm i craco-less -D
```