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