• React.useCallback(function,array)使用,React中的函数组件和类组件的取值(快照or最新值)


    目录

    React.useCallback(function,array)

    React.memo

    示例1

    示例2

    React中的函数组件和类组件的取值(快照or最新值)

    闭包例子

    修改React例子


    React.useCallback(function,array)

    返回一个函数,只有在array中的依赖项变化的时候才会更新(返回一个新的函数)。

    使用场景:当父组件传入子组件函数时,由于React.memo进行的是浅比较,重新渲染时,函数的引用是发生改变的,所以会导致子组件重新渲染,而用useCallback后只要依赖的变量未发生改变将始终返回同一个函数引用,不会导致子组件重新渲染。

    注意区别于useMemo 缓存的是函数的返回结果useCallback缓存的是函数

    React.memo

    React纯组件pureComponent、React.memo(FunComponent,compareFunction)、React.useMemo(callback,array)_YF-SOD的博客-CSDN博客

    示例1

    点击 Button1 的时候只会更新 Button1 和 Button3 后面的内容;

    点击 Button2 会将三个按钮后的内容都更新;

    点击 Button3 的也是只更新 Button1 和 Button3 后面的内容。

    没有用useCallback包括的函数,每次都会重新声明一个新的方法,新的方法尽管和旧的方法一样,但是依旧是两个不同的对象,React.memo对比后发现对象props改变,就重新渲染了。而用uesCallback包括的函数只有当依赖项改变时才会返回新的函数(对象),所以不会重新渲染。

    1. const Button = React.memo(({ onClickButton, children }) => {
    2. return (
    3. <>
    4. <button onClick={onClickButton}>{children}button>
    5. <span>{Math.random()}span>
    6. );
    7. });
    8. export default function App() {
    9. const [count1, setCount1] = useState(0);
    10. const [count2, setCount2] = useState(0);
    11. const [count3, setCount3] = useState(0);
    12. const handleClickButton1 = () => {setCount1(count1 + 1);}
    13. const handleClickButton2 = useCallback(() => {
    14. setCount2(count2 + 1);
    15. }, [count2]);
    16. return (
    17. <div>
    18. <div>
    19. <Button onClickButton={handleClickButton1}>Button1Button>
    20. div>
    21. <div>
    22. <Button onClickButton={handleClickButton2}>Button2Button>
    23. div>
    24. <div>
    25. <Button onClickButton={() => {setCount3(count3 + 1); }}>
    26. Button3
    27. Button>
    28. div>
    29. div>
    30. );
    31. }
    32. const rootElement = document.getElementById("root");
    33. ReactDOM.render(<App />, rootElement);

    示例2

    useCallback - 简书

    React中的函数组件和类组件的取值(快照or最新值)

    下面先点击弹框按钮再点击double,alert中的数值,在类组件中始终显示的是最新的。而在函数组件中始终显示的是点击弹框时的数值(快照)而不是double后的数值。

    1. import React, { useState } from "react";
    2. class ClassProfilePage extends React.Component<any,any> {
    3. showMessage = () => {
    4. alert('Followed ' + this.props.user);
    5. };
    6. handleClick = () => {
    7. setTimeout(this.showMessage, 3000);
    8. };
    9. render() {
    10. return <button onClick={this.handleClick}>Followbutton>;
    11. }
    12. }
    13. function FunctionProfilePage(props) {
    14. const showMessage = () => {
    15. alert('Followed ' + props.user);
    16. };
    17. const handleClick = () => {
    18. setTimeout(showMessage, 3000);
    19. };
    20. return (
    21. <button onClick={handleClick}>Followbutton>
    22. );
    23. }
    24. function App() {
    25. const [state,setState] = useState(1);
    26. return (
    27. <div className="App">
    28. <button onClick={() => {
    29. setState(x => x+x);
    30. }}>doublebutton>
    31. <div>state:{state}div>
    32. <FunctionProfilePage user={state} /> // 点击始终显示的是快照值
    33. <ClassProfilePage user={state} /> // 点击始终显示的是最新值
    34. div>
    35. );
    36. }
    37. const rootElement = document.getElementById("root");
    38. ReactDOM.render(<App />, rootElement);

    理解为在类组件中是挂载在this的引用上所以始终拿到的是最新的值,而在函数组件中是最新值。 

    闭包例子

    1. for(var i=0;i<10;i++){
    2. setTimeout(() => console.log('val:',i)) // 拿到的是最新值
    3. }
    4. for(var i=0;i<10;i++){
    5. setTimeout(((val) => console.log('val:',val)).bind(null,i)); // 拿到的是快照
    6. }
    7. const ref = {current: null}
    8. for(var i=0;i<10;i++){
    9. ref.current = i;
    10. setTimeout(((val) => console.log('val:',ref.current)).bind(null,ref)); // 拿到的是最新值
    11. }
    12. for (var i = 0; i < 10; i++) { // 拿到的是快照
    13. let t = i;
    14. setTimeout(() => {
    15. console.log("t:", t);
    16. });
    17. }

    修改React例子

    可以通过下面修改在类组件中打印快照值。

    1. showMessage = (message) => {
    2. alert('Followed ' + message);
    3. };
    4. handleClick = () => {
    5. const message = this.props.user // 在触发异步函数之前保存快照
    6. setTimeout(()=>{this.showMessage(message)}, 3000);
    7. };

    可以通过下面修改在函数组件中打印最新值(ref存取最新值)。

    1. const ref = useRef("");
    2. useEffect(() => {
    3. ref.current = props.user;
    4. });
    5. const showMessage = () => {
    6. console.log('ref:',ref)
    7. alert("Followed " + props.user +',' + ref.current);
    8. };

  • 相关阅读:
    136. 只出现一次的数字(hot100)
    Android数据库处理重复插入Insert数据的问题
    [NLP]LLM---大模型指令微调中的“Prompt”
    Qt入门(零)——Qt概述
    SAP接口调用方式总结
    朴实无华的三天每日一题
    CVPR 2022 Oral 大连理工提出的SCI 快速、超强的低光照图像增强方法 亲测效果
    Centos7 安装nvidia显卡驱动
    计算机通识——多媒体参数
    多输入多输出 | MATLAB实现PSO-RBF粒子群优化径向基神经网络多输入多输出预测
  • 原文地址:https://blog.csdn.net/AIWWY/article/details/127954251