函数组件和类组件区别:
1.函数组件中没有this
2.函数组件无需继承
3.函数组件默认没有状态,想要使用组件状态必须通过 HOOK 函数引入
4.函数组件默认没有生命周期函数
5.函数组件的渲染,只需要一次函数调用即可
useState :用来管理组件的状态, 当下主要用来给函数式组件添加状态.
对于引用类型的组件状态,必须传入一个全新的状态值(地址也得是全新的),因此要浅拷贝或者深拷贝
注意:在set修改之后,比如log语句可能获取不到最新的值,解决:useEffect生命周期监听可解决
useEffect(用于计数属性会闪烁) 和 useLayoutEffect(用于计算属性,会白屏):用来给函数式组件添加生命周期方法. 可监听,(很像Vue中的watch)
函数组件中没有生命周期,那么可以使用 useEffect 来替代。如果你熟悉 React class的生命周期函数,你可以把 useEffect Hook 看做 componentDidMount, componentDidUpdate 和 componentWillUnmount 这三个函数的组合.
写法1. useEffect 的第一个参数回调函数,在组件初次渲染 和 依赖数组中监听的状态变量发生改变时都会执行
写法2. useEffect 的第一个参数回调函数,在组件初次渲染 和 后续每次更新时都会执行
写法3.useEffect 的第一个参数回调函数,只在组件初次渲染时执行一次(类似类组件componentDIdMount):可以在这里发请求,创建定时器,监听事件
记得卸载组件:销毁定时器,取消监听事件
useEffect 和 useLayoutEffect区别:(根据需求来)
useEffect 中的代码是异步执行的,而且是在组件渲染完成后执行的,(缺点:容易出现闪屏:执行了两次,初始值,渲染后值)优点:不会阻塞组件更新
解决:
useLayoutEffect 中的代码是同步执行的,而且是在组件渲染完成前执行(优点:没有闪屏)缺点:会阻塞组件更新,可能会导致页面长时间空白,得不到响应
useRef 写在标签 通过 current属性获取dom节点
useRef 写在组件上,子组件通过 forwordRef对外暴露方法,子中可使用父传来的值
(子需要对外暴露方法,需要配合高阶组件useImperativeHandle,父中才能使用子中方法)但是子貌似无法使用父传来的值了父为null
useRef:定义ref引用,通过current属性获取dom节点:注意需要在组件渲染完成后再获取dom节点
父组件:
子组件:获取子组件方法:forwardRef对外暴露方法需要配合:useImperativeHandle
想暴露方法给父组件:通过高阶组件forwardRef对外暴露方法需要配合:useImperativeHandle钩子函数暴露
不想暴露方法给父组件:就无需配合useImperativeHandle钩子函数
函数式跨组件通信: useContext 实现跨组件传值,内层组件获取context中的值
用来解决同一个父组件的后代组件之间的数据共享问题, 同一个父组件的所有后代组件都可以用 useContext() 从最近的 context 中获取.
函数跨组件通信:// 先配置 utils文件夹下,context.ts:createContext创建实例化通信对象
父导入通信对象,创建context.Provider组件 , value 传值,包裹子组件。
子组件中包裹 组件,
孙子导入通信对象,使用 useContext 和通信对象建立联系。从中获取value传来的值
utils文件夹下,context.ts
// utils文件夹下,context.ts
import { createContext } from 'react'
// 实例化通信对象
export default createContext(0)
祖先标签:导入通信对象 ,value传值,包裹
子组件
孙子组件导入通信对象,使用 useContext 和通信对象建立联系,从中获取value 传来的值
Hooks 的使用规则
只在顶层调用 Hooks : Hooks 的调用尽量只在顶层作用域
不要在循环、条件或嵌套函数中调用 Hook,否则可能会无法确保每次组件渲染时都以相同的顺序调用 Hook
只在函数组件调用 Hooks:目前只支持函数式组件,未来版本 Hooks 会扩展到 class 类组件;
React Hooks 的应用场景:函数式组件、自定义 Hooks