课程目标
- 掌握受控组件的使用;
- 掌握基于 SCU 及 PureComponent 的组件渲染优化;
- 掌握 Ref 属性的使用。
内容
受控组件
- 当想要获取表单的一些内部状态时,就可以将表单的内部状态和组件的状态进行绑定,这样就形成受控组件;
- 受控组件:checked 或 value;
- 非受控组件:defaultChecked 或 defaultValue;
- 通过表单对应的事件 onChange 将表单内部状态和组件的状态进行绑定(双向绑定)。
基于 SCU 或 PureComponent 的组件更新优化
- PureComponent 提供了一个具有浅比较的 shouldComponentUpdate 方法,其它和 Component 完全一致;
- 父组件更新都会引起子组件更新,通过 SCU 进行控制子组件是否需要更新
key 的取值问题
- key:给列表中的元素添加一个标记(id),方便在更新前后用于对比;
- 在 React 中,组件每次更新时,会生成一个虚拟 DOM,和原有的虚拟 DOM 进行对比,如果是批量生成的一组元素,那 React 就会根据 key 值去做对比;
- 一个列表中的每一项 key 是唯一的,如果列表中发生顺序等操作变化,key 值建议使用数据的 id;
- key 的取值原则:
- 在同一列表中,key 值唯一;
- 更新前后,同一元素的 key 值不能变;
- 建议 key 使用数据的 id。
ref
- createRef();
import { PureComponent, createRef } from 'react'; class Todas extends PureComponent { // 实例成员属性 todosCom = createRef(); componentDidMount() { this.todosCom.current.style.background = 'yellow'; } render() { return ( <div id="todos" ref={this.todosCom}> ... </div> ) } }
- ref 的另外一种用法:
import { PureComponent } from 'react'; class Todas extends PureComponent { componentDidMount() { this.todosCom.style.background = 'yellow'; } render() { return ( <div id="todos" ref={ref => this.todosCom = ref}> ... </div> ) } }
- 注意:在组件挂在完成之后及更新之后使用;
children
- 组件标签对之间的内容会被当做一个特殊的属性
props.children
传入组件内容(类似于 vue 中的插槽); - app.js
import React, { PureComponent } from 'react'; import Count from './Count'; import Num from './Num'; class App extends PureComponent { constructor(props) { super(props); this.state = { } } render() { return ( <Count> <p>这里是 App</p> <Num /> {() => { console.log('这是函数'); return <div>这是函数</div> }} </Count> ); } } export default App;
- num.js
import React, { PureComponent } from 'react'; class Num extends PureComponent { state = { num: 0 } render() { const { num } = this.state; return ( <> <div>{num}</div> <button onClick={()=>{this.setState({num: num+1})}}>递增</button> </> ); } } export default Num;
- count.js
import React, { PureComponent } from 'react'; class Count extends PureComponent { render() { const { children } = this.props; return ( <> {children[0]} {children[1]} {children[2]()} </> ); } } export default Count;
- 当然,也可以直接将内容通过 children 属性传递下去
<Count children={[ <p>这里是 App</p>, <Num />, () => { console.log('这是函数'); return <div>这是函数</div> } ]} > </Count>
- 可以自定义结构的组件常用形式:
- children;
- 传递函数;
- 传递子组件。
总结
- state 是不可变值,在修改 state 值时,不要修改原有的 state,而是根据原有的 state 映射出修改后的 state;