<react>学习笔记
JSX
- 最外层只允许被一个标签包裹
- 标签一定要闭合
- DOM元素和组件元素(组件元素要大写开头),也可以使用命名空间方式使用组件(<MUI.Button />)
- 注释:
1 | {/* 注释 */} |
- 元素属性:特殊:class->calssName for->htmlfor,自定义属性需要小驼峰写法
- Boolean 属性:省略的话默认为true 比如 disabled
- 展开属性:<Component {…data} />,使用ES6展开运算符
- DOM元素自定义HTML属性: data- 无障碍属性 aria-
- JavaScript属性表达式:
1 | const person = <Person name={window.isLoggedIn ? window.name : ''} /> |
- HTML转义:react会将所有显示到DOM的字符串转义,防止xss
react数据流
state
- 使用setState更新state
props
- 是properties的简写
- props默认值
1 | import React,{Component} from 'react' |
- 子组件prop–children:代表组件的子组件集合
- 组件props:props可以传入DOM节点,组件节点
- 子组件修改props,通过父组件传递的prop函数修改
react生命周期
1 | componentWillMount(){ |
组件挂载时
- componentWillMount与componentDidMount会在初始化时运行一次
- 如果在componentDidMount中运行setState那么组件会再次更新,在初始化过程中会渲染两次组件
组件卸载时
- componentWillUnmount执行,可以执行一些清理方法,比如时间回收、定时器清除
组件自身state更新
- 会依次执行shouldComponentUpdate、componentWillUpdate、componentDidUpdate
- shouldComponentUpdate接收需要更新的props和state,可以通过返回true/false判断是否更新组件
- 注意:不能在componentWillUpdate中执行setState
父组件更新props的更新
- 依次执行componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、componentDidUpdate
ReactDom
事件系统
合成事件
- React基于Virtual DOM实现了合成事件
- 合成事件支持事件冒泡机制,可以使用stoPropagation()和preventDefault()中断
- JSX中必须使用小驼峰书写事件属性名:onClick
- 合成事件实现机制
- 事件委托:react不会把事件处理直接绑定到真实节点上,而是把所有事件绑定到结构的最外层,使用统一的事件监听器,简化了事件处理和回收机制,提升效率。
- 自动绑定:使用ES6 class和纯函数时,事件方法上下文不会指向该组件,需要手动绑定this
1 | //bing绑定 |
原生事件
- componentDidMount中可以绑定原生事件
- 注意一定要手动移除原生事件绑定,否则会造成内存泄漏
1 | componentWillUnmount(){ |
合成与原生混用
- 绑定相同元素原生事件先调用
- 合成事件阻止冒泡只对合成事件起作用
- 原生事件阻止冒泡会影响合成事件
组件建通信
父向子通信
- 通过props传递
子向父
- 利用回调函数:
- 利用自定义事件机制:
跨级通信
- 使用context实现:
没有嵌套关系的组件通信
- 使用EventEmitter
1 | //event.js |
1 | //组件中使用 |
组件间抽象
mixin
- 使用createClass构建组件时提供了mixin属性
- 官方pureRenderMixin
- 如果是React的生命周期方法,会叠加在一起顺序执行
- React中不允许出现普通方法的mixin,会包ReactClassInterface错误
- createClass使用mixin做了两件事:1.共享工具方法 2.生命周期继承(props与state合并,生命周期方法合并)
- ES6 Classes与decorator
- ES6可以使用decorator实现mixin
mixin存在的问题
- 破坏原有组件封装性,需要维护‘不可见’状态
- 命名冲突,尤其对于第三方引用
- 增加复杂性,生命周期过多
高阶组件
- 高阶函数:函数接收函数作为输入,或者输出一个函数
- 高阶组件会返回一个增强的React组件
属性代理
1 | import React,{Component} from 'react' |
- 可以通过高阶组件传递props,这种方式成为属性代理
- 原始组件具备高阶组件对他的修饰,保持单个组件的封装同时还保持了易用性
- 功能
- 控制props
- 通过refs使用引用
- 抽象state
- 使用其他元素包裹WrappedComponent
反向继承
1 | import React,{Component} from 'react' |
- 渲染劫持
- 控制state
高阶组件命名
- 高阶组件会失去原始WrappedComponent的displayName
- 可以参照react-redux中getDiaplayName实现
- 可以使用recompose库,已经停止更新。。。可以使用Hooks解决这些问题
高阶组件参数
- 使用闭包传参
PureRender
纯函数
三大原则:1.给定相同的输入,总是返回相同的输出 2.过程没有副作用(不改变外部状态) 3.没有额外的状态依赖(不与第三方共享变量)
组件满足纯函数条件:被相同的props和state渲染得到相同的结果
Hooks
useState
1 | import React, { useState,useEffect } from "react"; |
useEffect
1 | import React, { useState,useEffect } from "react"; |