react17笔记1

hooks

react类组件(class)写法中,有setState和生命周期对状态进行管理,但是在函数组件中不存在这些,故引入hooks(版本:>=16.8),使开发者在非class的情况下使用更多react特性。

useEffect相当于componentDidMount和componentDidUpdate两个生命周期,通过return () => {}的方式解绑生命周期,相当于componentWillUnmount周期,以监听页面滚动为例,通过effect实现监听与解绑如下:

useEffect(() = >{undefined
window.addEventListener(‘scroll’, throttleFunc)
return () = >{undefined
window.removeEventListener(‘scroll’, throttleFunc)
}
}, [])

在同一个effect钩子中实现绑定与解绑,使状态的管理更加方便、代码更简洁。

此外还有发生在页面渲染前的useMemo相当于shouldComponentUpdate周期等

结论:使用hooks的函数组件,简化了很多代码,不用维护复杂的生命周期,也不用担心this的指向问题。

hooks主要有以下特点:

1、无需修改组件结构的情况下复用状态逻辑;

2、可将组件中相互关联的部分拆分成更小的函数,复杂组件将变得更容易理解;

3、每一个组件内的函数(包括事件处理函数,effects,定时器或者api调用等等)会捕获某次渲染中定义的props和state;

4、memo缓存组件 ,useMemo缓存值, useCallback缓存函数

5、每次render都有自己的props、state和effects。(每一个组件内的函数,包括事件处理函数,effects,定时器或者api调用等等,会捕获某次渲染中定义的props和state);

6、**更新状态的时候(如setCount(count + 1)),React会重新渲染组件,**每一次渲染都能拿到独立的count状态,这个状态值是函数中的一个常量;

7、没有了显性的生命周期,所有渲染后的执行方法都在useEffect里面统一管理;

8、函数式编程,不需要定义constructor、render、class;

9、某一个组件,方法需不需要渲染、重新执行完全取决于开发者,方便管理。

1.3 常见hook

useState、useEffect、useMemo、useCallback、useRef、useContext、useReducer…。

结论:setState返回的函数执行会导致re-render;
框架内部会对多次函数操作进行合并,保证useState拿到最新的状态,避免重复渲染。

如果初始state需要通过复杂计算获得,可以传入一个函数,在函数中计算并返回初始state,此函数只在初始渲染时被调用,具体如下:

const [count, setCount] = useState(() => {
  const initialCount = someExpensiveComputation(props)
  return initialState
})

类组件的state依赖上一次state,函数组件的state是重新执行当前函数。

结论:effect在页面完成渲染后按照先后顺序执行,并且内部执行时异步的

useEffect和useLayoutEffect:
useLayoutEffect也是一个hook方法,跟useEffect类似,区别在于渲染时机不同,useEffect发生在浏览器渲染结束后执行,useLayoutEffect则是发生在dom更新完成后。

包含useEffect的组件整个运行过程如下:
1、触发组件重新渲染(通过改变组件state或者组件的父组件重新渲染,导致子节点渲染)
2、组件函数执行
3、组件渲染后呈现到屏幕上
4、useEffect hook执行

包含useLayoutEffect的组件整个运行过程如下:
1、触发组件重新渲染(通过改变组件state或者组件的父组件重新渲染,导致子组件渲染)
2、组件函数执行
3、useLayoutEffect hook执行, React等待useLayoutEffect的函数执行完毕
4、组件渲染后呈现到屏幕上

useEffect异步执行的优点是,react渲染组件不必等待useEffect函数执行完毕,造成阻塞。

百分之99的情况,使用useEffect就可以了,唯一需要用到useLayoutEffect的情况就是,在使用useEffect的情况下,我们的屏幕会出现闪烁的情况(组件在很短的时间内渲染了两次)

2.4 useMemo

参数是创建函数和依赖项数组。

返回值是一个带有memoized的值,发生在render之前, 并且这个值仅在依赖项改变时才重新计算。

结论:useMemo发生在render前,返回一个缓存的数据,且仅在依赖项改变后变化。

使用useMemo可以避免多余的计算开销。

不同之处

useCallback 优化针对于子组件的渲染(一般子组件使用 memo() 函数)
useMemo 优化针对于当前组件高开销的计算

useMemo 和 useCallback 接收的参数都是一样,第一个参数为回调 第二个参数为要依赖的数据

共同作用:
1.仅仅 依赖数据 发生变化, 才会重新计算结果,也就是起到缓存的作用。

两者区别:

useCallback 和 useMemo 的区别是useCallback返回一个函数,当把它返回的这个函数作为子组件使用时,可以避免每次父组件更新时都重新渲染这个子组件
1.useMemo 计算结果是 return 回来的值, 主要用于 缓存计算结果的值 ,
应用场景如: 需要 计算的状态

const increment1 = useMemo(()=>{
	return Math.random(count);
},[count])

2.useCallback 计算结果是 函数, 主要用于 缓存函数,
应用场景如: 在将一个组件中的函数,传递给子元素进行回调使用时,使用useCallback对函数进行处理
需要缓存的函数,因为函数式组件每次任何一个 state 的变化 整个组件 都会被重新刷新,一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。

const increment2 = useCallback(()=>{
	setCount(count + 1);
},[count])

3.useMemo替代useCallback

const increment2 = useMemo(()=>{
	return () = > {
	setCount(count + 1);
	}
},[count])

注意: 不要滥用,会造成性能浪费,react中减少render就能提高性能,所以这个仅仅只针对缓存能减少重复渲染时使用和缓存计算结果。
 

memo() 函数


const MyComponent = React.memo(function MyComponent(props) {
  /* 使用 props 渲染 */
});
React.memo 会在渲染之前检查 props 的变更,在 props 发生改变时才会重新渲染组件。但是
如果函数组件被 React.memo 包裹,且其实现中拥有 useState,useReducer 或 useContext 的 Hook,当 context 发生变化时,它仍会重新渲染。

2.6 useRef

返回值是一个可变的ref对象,并且这个对象的值发生改变时不会引起页面的渲染。

结论:useRef可以存储不需要引起页面渲染的数据;修改useRef值的唯一方法是修改.current,且修改后不会引起重渲染。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值