组件化思想
组件
组件是构建 React 应用的独立、可复用的代码块。它接收输入(称为 props),并返回描述UI的 React 元素。
函数组件 vs 类组件
- 函数组件:一个接受输入,并输出JSX的函数。
- 类组件:使用class定义,并继承React.Component的类,必须包含一个render()方法。
为什么函数组件成为主流
1、代码简洁:函数组件的语法更简单,没有this绑定问题。
2、Hooks的引入:引入Hooks后,函数组件也能拥有状态和生命周期等能力。
受控组件 vs 非受控组件
- 受控组件:表单数据由React组件管理的组件。表单元素(input、textarea等)的值由state控制,并通过onChange事件来更新。
- 非受控组件:表单数据由DOM本身进行管理,可以使用ref从DOM节点中获取表单值。
状态和属性
state(状态)
- 组件内部管理的数据,状态改变会触发组件的重新渲染。
- 如何更新:
- 类组件:使用this.setState()
- 函数组件:使用useState Hook 返回更新函数
- 状态的更新是异步的,React会对同一个事件处理函数中的多个状态更新进行批处理
- 状态不可变,每次状态更新都会产生新的状态对象,直接修改状态不会重渲染
props(属性)
- 从组件外部传入的数据,类似函数的参数,只读,不能修改。
- 实现父组件向子组件通信(传递数据、回调函数等)
Hooks
1、useState
- 作用:在函数组件中添加内部状态
- 语法:const [state,setState] = useState(初始值)
- 关键点:初始值可以是一个值,也可以是一个函数。调用setState会替换状态对象
2、useEffect
- 作用:在函数组件中执行副作用操作(数据获取,订阅,手动修改DOM等一些异步操作)
- 执行时机:默认情况下,在每次渲染后(包括首次渲染)都会执行。
- 依赖数组(第二个参数)的控制:
- 不提供依赖数组(null):每次渲染后都执行
- 依赖数组为空([]):仅在组件挂载后执行一次(类似于componentDidMount)
- 依赖数组有值([dep1,dep2]):在组件挂载后以及dep1或dep2发生改变时执行
- 清除效应:如果useEffect的回调函数返回一个函数,这个函数会在组件卸载前和执行下一个副作用之前被调用,可以用于清理(取消订阅、清除定时器等)
3、useContext
- 作用:接受一个Context对象(由React.createContext()创建)并返回该Context的当前值
- 实现与后代组件单向通信
4、useCallback和useMemo
- useCallback:缓存函数本身,用于优化性能。
- 在进行重新渲染时,
- 如果依赖项没有发生变化,返回的是相同的函数,从而跳过重新渲染。
- 当依赖项改变时,会更新函数,并重新渲染。
- useMemo:缓存计算结果,用于优化性能
- 避免每次重新渲染时都进行高开销的计算任务
- 仅在依赖项改变时重新计算。
在JS中每次运行function(){}和()=>{}都会生成新的函数对象。
父组件中定义了一个回调函数,子组件中调用了这个函数。当父组件状态改变时,会重渲染父组件,父组件中子组件也会重渲染,其中父组件重新生成了一个新的函数对象(虽然它的功能不变,但函数的引用变了,是一个新的对象),传入子组件的回调函数变了,所以子组件也要重新生成。
如果使用useCallback缓存该回调函数,只要依赖数组中的元素不变,当父组件重渲染时,它会返回缓存好的函数对象,而不是生成一个新的函数对象,传入子组件的回调函数不变,子组件跳过重新渲染。
5、useRef
- 访问DOM元素
- 存储一个可变的值
- ref的current属性可以在组件的整个生命周期内持久存在,而且改变它不会触发组件重新渲染,可以用来存储定时器ID,上一次属性或状态等。
生命周期和Hooks
- componentDidMount:组件挂载后回调
- 使用 useEffect 并提供一个空依赖数组 []。
- componentDidUpdate:组件状态更新时回调
- 使用 useEffect 并不提供依赖数组或提供一个非空的依赖数组
- 使用 useRef 来保存一个在组件生命周期内持久存在的值(isMounted),它不会触发重渲染。
- 首次渲染时,isMounted.current 为 false,将其设为 true 但不执行更新逻辑。
- 后续渲染时,isMounted.current 为 true,执行更新逻辑。
- componentWillUnmount :组件卸载之前回调
- 在 useEffect 中返回一个清理函数并提供一个空依赖数组。
虚拟DOM
一个轻量级的Javascript对象,是真实DOM的抽象,当组件状态改变时,React会先在虚拟DOM上进行比较计算,而不是直接操作DOM。
- 工作流程:
- 当状态改变时,会创建一个新的虚拟DOM树。
- 使用Diffing算法比较新旧两个虚拟DOM树,找出需要更新的最小部分
- 将计算出来的差异批量地应用到真实DOM上
- 减少对真实DOM树的操作,极大提高性能。开发者无需关心如何高效地更新UI,只需要关心数据状态。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |