一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情
8. react组件化开发2
8.1 ref
- 作用:React开发模式中需要操作DOM的情况,但是又不建议直接操作原生DOM,利用refs获取对应DOM
- 场景:
- 管理焦点,文本选择或媒体播放
- 触发强制动画
- 集成第三方DOM库
- 使用:
- 传入字符串: 通过this.refs.[String]获取对应元素[不推荐❌]
- 传入对象: 通过React.createRef()创建对象传入,获取时通过current属性得到对应元素[React推荐⭐️]
- 传入函数: 函数在DOM被挂载时回调,该函数传入一个元素对象并保存,获取时保存对象即可
- 类型:
- HTML元素:current属性 = 底层DOM元素
- 自定义class组件:current属性 = 接收组件挂载实例
- 函数组件不能使用ref属性(没有实例) -> 可以通过React.forwardRef获取DOM元素,利用hooks使用ref
8.2 受控组件[推荐🌟]
- 受控组件定义:表单数据管理由React组件控制
- 表单设置了value={this.state.value}属性,通过setState更新 -> state是React唯一数据源
- React渲染表单的组件[控制]用户输入过程的表单操作onChange={handle} -> handle(处理每次的state更新)
- React受控元素
- input-text : value=string, 回调值=event.target.value
- input-textarea : value=string, 回调值=event.target.value
- input-checkbox : value={boolean}, 回调值=event.target.checked
- input-radio : value={boolean}, 回调值=event.target.checked
- input-select : value=option/value, 回调值=event.target.value
8.3 非受控组件
- 表单数据由DOM节点处理
- 使用:
- 通过ref获取DOM节点的表单数据
- 通过defaultValue设置默认值
- 支持defaultChecked
- 支持defalutValue设置
8.4 高阶组件(Higher-Order Components, HOC)
-
高阶函数:
- 高阶函数定义:
- 接收一个(或多个)函数作为输入
- 输出一个函数
- 常用高阶函数:filter map reduce
- 高阶函数定义:
-
高阶组件定义:高阶组件的参数为组件,返回值为新的组件
-
调用过程:
- const EnhancedCpn = higherOrderComponent(WrappedComponent)
- function higherOrderComponent(WrappedComponent) {return newComponent}
-
notes:
- 高阶组件不是React API,是一个中基于React特性的设计模式
- 高阶组件常见于第三方库,eg: redux中的connect, react-router中的withRouter
-
组件名称:
- ES6中类表达式中类名可省略
- 组件名可以通过displayName修改
-
应用:
- props的增强:return(<WrappedConponent {...props} {...newProps}>)
- 渲染判断鉴权(Authentication):
- 生命周期劫持
-
高阶函数的意义:优雅处理React代码
- 早期React支持复用方式mixin --> Mixin可能互相依赖,相互耦合,不同Mixin方法可能冲突,组件处理更为复杂
- HOC缺陷:需要对原组件包裹或嵌套,调试更困难,可以劫持props,易造成冲突
- Hooks解决了很多React问题:this指向问题,hoc嵌套问题 etc.
其他:
- ref转发:
- ref不能用于函数式组件(无法获取实例),可以通过React.forwardRef高阶函数转发
- ref不能作为属性传递,React内部会进行管理
- Portals:
- 使得渲染的内容独立于父组件,甚至独立挂载于DOM元素中(id='root')
- 使用方法:ReactDOM.createProtal(child, container)
- child: 任何React子元素,eg.元素、字符串、fragment
- container: 一个DOM元素
- fragment:
- 包裹组件返回内容,替换用包裹的方式
- Fragment允许将子列表分组,而无需向DOM添加额外节点
- 使用: <> </>
- notes: 若需要添加key,则不可以用短标签
- 包裹组件返回内容,替换用
- StrictMode:
- <React.StrictMode />
- 作用:
- 不会渲染任何可见UI
- 为后代元素触发额外的检查和警告
- 仅在开发模式运行,不影响生产构建
- 影响:
- 应用程序任何部分启用,不影响未开启的组件
- 对包裹的组件及所有后代元素开启检查
- 检查内容:
- 不安全生命周期
- 使用过时的ref API
- 使用废弃的findDOMNode方法
- 检查意外副作用:eg. constructor调用两次
- 检查过时的context API:早期通过static属性声明Context对象属性,getChildContex返回Context对象.etc