IT评测·应用市场-qidao123.com

标题: react hooks--React.memo [打印本页]

作者: 悠扬随风    时间: 2024-9-22 19:48
标题: react hooks--React.memo
基本语法

React.memo 高阶组件的使用场景阐明:
React 组件更新机制:只要父组件状态更新,子组件就会无条件的一起更新。

注意:此处更新指的是组件代码实行、JSX 举行 Diff 操作(纯 JS 的操作,速率非常快,不会对性能产生太多影响)。

假如要避免组件 props 没有变化而举行的不须要更新(Diff),这种情况下,就要使用 React.memo 高阶组件。
注:对于 class 组件来说,可以使用 PureComponent 或 shouldComponentUpdate 钩子函数来实现。
  1. import { useState } from 'react'
  2. import ReactDOM from 'react-dom'
  3. const Child2 = ({ count }) => {
  4.   console.log('Child2 子组件代码执行了')
  5.   return <div style={{ backgroundColor: '#abc' }}>子组件2:{count}</div>
  6. }
  7. const Child1 = () => {
  8.   console.log('Child1 子组件代码执行了')
  9.   return <div style={{ backgroundColor: '#def' }}>子组件1</div>
  10. }
  11. const App = () => {
  12.   const [count, setCount] = useState(0)
  13.   return (
  14.     <div style={{ backgroundColor: 'pink', padding: 10 }}>
  15.       <h1>计数器:{count}</h1>
  16.       <button onClick={() => setCount(count + 1)}>+1</button>
  17.       <hr />
  18.       {/* 子组件 */}
  19.       <Child1 />
  20.       <br />
  21.       <Child2 count={count} />
  22.     </div>
  23.   )
  24. }
  25. export default App
复制代码

语法:
使用场景:当你想要避免函数组件 props 没有变化而产生的不须要更新时,就要用到 React.memo 了。
作用:影象组件上一次的渲染结果,在 props 没有变化时复用该结果,避免函数组件不须要的更新


表明:


原理:通过对比检查更新前后 props 是否雷同,来决定是否复用上一次的渲染结果


并不是所有的组件都适合使用memo,比如child2组件,每次都需要重新渲染,使用memo反而会使性能变得更低,逻辑也变得更复杂

基本用法

假如你的组件在雷同 props 的情况下渲染雷同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过影象组件渲染结果的方式来进步组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果
React.memo 仅检查 props 变更。假如函数组件被 React.memo 包裹,且其实现中拥有 useStateuseReduceruseContext 的 Hook,当 state 或 context 发生变化时,它仍会重新渲染。
默认情况下,React.memo 只会对更新前后的 props 举行浅对比(shallow compare)与 PureComponent 雷同。

也就是说,对于对象范例的 prop 来说,只会比力引用


默认情况下其只会对复杂对象做浅层对比,假如你想要控制对比过程,那么请将自定义的比力函数通过第二个参数传入来实现
假如你要手动控制比力过程,可以使用 React.memo 的第二个参数:


表明:

子组件Callback.jsx
  1. export default function Callback() {
  2.     console.log('callback')
  3.     return (
  4.         <div>callback</div>
  5.     )
  6. }
复制代码

父组件App.jsx:
  1. import Callback from './components/Callback'
  2. import {useState} from "react";
  3. export default function App() {
  4.     const [age, setAge] = useState(20);
  5.     function changeAge() {
  6.         setAge(age + 1)
  7.     }
  8.   return (
  9.       <div>
  10.           age: {age}
  11.           <button onClick={changeAge}>修改age</button>
  12.           <Callback />
  13.       </div>
  14.   )
  15. }
复制代码
修改父组件的state值后,函数子组件内部的代码运行了,相对而言有点费性能
优化如下:
使用React.memo包裹子组件,缓存上一次的结果,默认情况下其只会对复杂对象做浅层对比,假如你想要控制对比过程,那么请将自定义的比力函数通过第二个参数传入来实现。

子组件Callback.jsx
  1. import React from 'react';
  2. function Callback() {
  3.     console.log('callback')
  4.     return (
  5.         <div>callback</div>
  6.     )
  7. }
  8. ++ export default React.memo(Callback)
复制代码
优化后,父组件的state数据变更后,没有实行打印结果。
在父组件中定义个fn函数传入到子组件中:
  1. import Callback from './components/Callback'
  2. import { useState} from "react";
  3. export default function App() {
  4.     console.log('app')
  5.     const [age, setAge] = useState(20);
  6.     function changeAge() {
  7.         setAge(age + 1)
  8.     }
  9.     function fn() {
  10.         
  11.     }
  12.   return (
  13.       <div>
  14.           age: {age}
  15.           <button onClick={changeAge}>修改age</button>
  16.           <Callback fn={fn} />
  17.       </div>
  18.   )
  19. }
复制代码
此时,父组件的state数据改变后,会引起子组件的内部代码运行。打印告终果,相对而言性能有斲丧。

优化如下:
useCallback优化性能
fn函数通过useCallback缓存起来
  1. import Callback from './components/Callback'
  2. import {useCallback, useState} from "react";
  3. export default function App() {
  4.     console.log('app')
  5.     const [age, setAge] = useState(20);
  6.     function changeAge() {
  7.         setAge(age + 1)
  8.     }
  9.    
  10.     let fn = useCallback(() => {}, [])
  11.   return (
  12.       <div>
  13.           age: {age}
  14.           <button onClick={changeAge}>修改age</button>
  15.           <Callback fn={fn} />
  16.       </div>
  17.   )
  18. }
复制代码
此时修改父组件的state数据没有引起子组件的内部代码运行
因为fn函数被缓存了,地址没有发生改变,React.memo就认为props数据没有发生改变,所以没有表要重新运行函数。

useCallback怎样做的性能优化?


总结

useMemo 用于缓存一些耗时的计算结果(返回值),只有当依赖项改变时才重新举行计算。 useCallback(func, [deps]) 等同于 useMemo(() => func, [deps]) useCallback 缓存的是方法的引用,useMemo 缓存的是方法的返回值,实用场景都是避免不须要的子组件渲染。 在类组件中有 React.PureComponent,与之对应的函数组件可以使用 React.memo,它们都会在自身 re-render 时,对每一个 props 项举行浅对比,假如引用没有发生改变,就不会触发渲染。 那么,useMemo 和 React.memo 有什么共同点呢?前者可以在组件内部使用,可以拥有比后者更细粒度的依赖控制。它们两个与 useCallback 的本质一样,都是举行依赖控制。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4