7-13 函数式组件(class组件简写)
- 纯函数, 输入props, 输出JSX 2. 没有实例, 没有生命周期, 没有state 3.不能扩展其他方法
适用场景? clss组件转函数式组件写法?
7-14 React非受控组件
- ref 2. defaultValue、 defaultChecked 3.手动操作 DOM 元素
使用场景:
- 必须手动操作DOM元素, setState 实现不了
- 文件上传
- 某些富文本编辑器, 需要传入DOM 元素
如何选择受控 VS 非受控组件
- 优先使用受控组件, 符合React 设计原则(数据驱动)
- 必须操作DOM 时, 再使用非受控组件
7-15 Portals(传送门)
Portals 提供了一种很好的方法,将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点。ReactDOM.createPortal(child, container)
第一个参数(child
)是任何可渲染的 React 子元素,例如一个元素,字符串或 片段(fragment)。第二个参数(container
)则是一个 DOM 元素。
- 组件默认会按照既定层次嵌套渲染
如何让组件渲染到父组件以外
render() {
return ReactDOM.createPortal(
<div className="modal">{ this.props.children }</div>
, document.body) }
Portals
适合脱离文档流(out of flow) 的组件, 比如模态框,通知,警告,goTop 等。使用场景:
1.overflow: hidden 2. 父组件z-index 值太小 3. fixed 需要放在 body 第一层级 4. position: absolute
与 position: fixed
的组件。
7-16 context(上下文)生产 -> 消费
场景:公用信息(语言、主题)、 用props太繁琐、 用redux小题大做
上下文(Context) 提供了一种通过组件树传递数据的方法,无需在每个级别手动传递 props 属性 。例如, 身份、主题、语言。
const ThemeContext = React.createContext('light'); // 默认值
<ThemeContext.Provider value="dark"> // 生产
<Toolbar />
</ThemeContext.Provider>
// 消费( class组件)
static contextType = ThemeContext; // 等价与函数外部写法 class.contextType = ThemeContext
render() {
let value = this.context;
}
// 消费 (函数组件)
<ThemeContext.Consumer> {value => /* render something based on the context value */} </ThemeContext.Consumer>
7-17 异步组件
import() 、 React.lazy、 React.Suspense
const classComp = React.lazy(() => import('./ContextDemo'))
<React.Suspense fallback={<div>Loading...</div>}>
<ContextDemo/>
</React.Suspense>