useCallback()和useMemo()

useMemo()和useCallback()都能够起到缓存的作用,只不过useMemo()针对于数据,useCallback()针对于函数

useMemo()

不使用useMemo()

当点击按钮时会改变value的值,同时也会一直执行console.log(1),即take函数一直在被调用

import React, { useState, useMemo } from 'react'

export default function UseMemo() {
  const [value, setvalue] = useState(0)
  const [count, setcount] = useState(1)
  const take = (count) => {
    console.log(1)
    return count * 3
  }
  const price = take(count)

  return (
    <div>
      <p>value:{value}   count:{price}</p>
      <button onClick={() => setvalue(value + 1)}>value+1</button>
    </div>
  )
}

使用useMemo

使用useMemo()包裹后,点击按钮不会引起take函数的执行,price的值始终都是从缓存里面拿到的,只有在后面的依赖里面添加了依赖,且依赖的值改变了,才会执行被包裹的代码,对性能有一定的提升

import React, { useState, useMemo } from 'react'

export default function UseMemo() {
  const [value, setvalue] = useState(0)
  const [count, setcount] = useState(1)
  const take = (count) => {
    console.log(1)
    return count * 3
  }
  const price = useMemo(() => {
    return take(count)
  }, [])
  return (
    <div>
      <p>value:{value}   count:{price}</p>
      <button onClick={() => setvalue(value + 1)}>value+1</button>
    </div>
  )
}

useCallback()

不使用useCallback()的情况,每次组件更新,函数都会重新创建,此时每点击一次按钮,score会加1,同时可以观察到控制台输出的值也是增加的

App.js

import logo from './logo.svg';
import { useState, useCallback } from 'react';
import './App.css';
// import UseMemo from './hooks/03-useMemo'
import UseCallback from './hooks/04-useCallback';


function App() {
  const [score, setscore] = useState(0)
  const [money, setmoney] = useState(1)
  // const showScore = useCallback(() => {
  //   console.log(money)
  //   console.log(score)
  // }, [money])

  const showScore = () => {
    console.log(money)
    console.log(score)
  }


  return (
    <div className="App">

      <UseCallback test={test} setscore={setscore} score={score} money={money} showScore={showScore} setmoney={setmoney} />
    </div>
  );
}

export default App;

UseCallback.js

import { setSelectionRange } from '@testing-library/user-event/dist/utils'
import React, { useCallback, useState } from 'react'

export default function UseCallback({ test, setscore, score, money, setmoney, showScore }) {
  return (
    <div>
      <p>{money},{score}</p>
      <button onClick={() => {
        // setmoney(money + 2)
        setTimeout(() => {
          setscore(score + 1)
          // test()
          showScore()
        }, 1000);
      }}>按</button>
    </div>
  )
}

使用useCallback()的情况,由于点击按钮变化的是score,而添加的依赖是count,所以组件更新是调用的函数始终是缓存的函数,控制台上输出的值也就是缓存的值,不会实时更新

App.js

import logo from './logo.svg';
import { useState, useCallback } from 'react';
import './App.css';
// import UseMemo from './hooks/03-useMemo'
import UseCallback from './hooks/04-useCallback';


function App() {
  const [score, setscore] = useState(0)
  const [money, setmoney] = useState(1)
  const showScore = useCallback(() => {
    console.log(money)
    console.log(score)
  }, [money])

  // const showScore = () => {
  //   console.log(money)
  //   console.log(score)
  // }


  return (
    <div className="App">

      <UseCallback setscore={setscore} score={score} money={money} showScore={showScore} setmoney={setmoney} />
    </div>
  );
}

export default App;

UseCallback.js

import { setSelectionRange } from '@testing-library/user-event/dist/utils'
import React, { useCallback, useState } from 'react'

export default function UseCallback({ setscore, score, money, setmoney, showScore }) {
  return (
    <div>
      <p>{money},{score}</p>
      <button onClick={() => {
        // setmoney(money + 2)
        setTimeout(() => {
          setscore(score + 1)
          // test()
          showScore()
        }, 1000);
      }}>按</button>
    </div>
  )
}

 

本文转载于网络 如有侵权请联系删除

相关文章

  • 试题 算法提高 笨小猴

    资源限制时间限制:1.0s内存限制:256.0MB问题描述  笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!   这种方法的具体描述如下:假设maxn是单词中出现次数最多的字母的出现次数,minn是单词中出现次数最少的字母的出现次数,如果maxn-minn是一个质数,那么笨小猴就认为这是个LuckyWord,这样的单词很可能就是正确的答案。输入格式  输入文件只有一行,是一个单词,其中只可能出现小写字母,并且长度小于100。输出格式  输出文件共两行,第一行是一个字符串,假设输入的的单词是LuckyWord,那么输出“LuckyWord”,否则输出“NoAnswer”;第二行是一个整数,如果输入单词是LuckyWord,输出maxn-minn的值,否则输出0。样例输入error样例输出LuckyWord 2样例说明  单词error中出现最多的字母r出现了3次,出现次数最少的字母出现了1次,3-1=2,2是质数。样例输入olympic样例输出NoAnswer 0样例说明  单词olympic中所有字

  • 白话Elasticsearch46-深入聚合数据分析之Cardinality Aggs-cardinality去重算法以及每月销售品牌数量统计

    概述继续跟中华石杉老师学习ES,第46篇课程地址:https://www.roncoo.com/view/55官方说明CardinalityAggregation:戳这里es中的去重,cartinalitymetric,对每个bucket中的指定的field进行去重,取去重后的count,类似于count(distcint)示例GET/tvs/sales/_search { "aggs":{ "month":{ "date_histogram":{ "field":"sold_date", "interval":"month" }, "aggs":{ "distinct_brand_cnt":{ "cardinality":{ "field":"brand" } } } } }, "size":0 }复制返回:{ "to

  • springboot整合shiro实现认证​

    Part2今日主题:springboot整合shiro1简介shiro是一款安全框架,可以控制登录,可以保证安全,对于我们来说一些接口的安全必须通过安全框架来控制,防止别人蓄意刷接口。2原理我还是要讲一下他的原理吧,如果这个人没有经过登录页面,去访问其他页面,shiro框架会将请求转发到登录页面去,让这个人登录,登录成功之后会给前端一个token,前端将token保存下来,每次去请求项目中的其他页面或者接口的时候,需要将token携带到请求头中,给后端,请求首先会经过拦截器,拦截器会对token进行判断,判断该token是否有效,如果有效,则放行,否则直接拦截了。3环境springboot4依赖我们需要shiro和jwt的依赖<!--自动依赖导入shiro-core和shiro-web--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</v

  • F5负载均衡会话保持技术及原理技术白皮书

    1.什么是会话保持? 在大多数电子商务的应用系统或者需要进行用户身份认证的在线系统中,一个客户与服务器经常经过好几次的交互过程才能完成一笔交易或者是一个请求的完成。由于这几次交互过程是密切相关的,服务器在进行这些交互过程的某一个交互步骤时,往往需要了解上一次交互过程的处理结果,或者上几步的交互过程结果,服务器进行下一步操作时需要这就要求所有这些相关的交互过程都由一台服务器完成,而不能被负载均衡器分散到不同的服务器上。而这一系列的相关的交互过程可能是由客户到服务器的一个连接的多次会话完成,也可能是在客户与服务器之间的多个不同连接里的多次会话完成。不同连接的多次会话,最典型的例子就是基于http的访问,一个客户完成一笔交易可能需多次点击,而一个新的点击产生的请求,可能会重用上一次点击建立起来的连接,也可能是一个新建的连接。会话保持就是指在负载均衡器上有这么一种机制,可以识别做客户与服务器之间交互过程的关连性,在作负载均衡的同时,还保证一系列相关连的访问请求会保持分配到一台服务器上。2.F5支持什么样的会话保持方法? F5BigIP支持多种的会话保持方法,其中包括:简单会话保持(源地址会话保

  • 判断ABAP代码是否处于update模式下运行的工具类

    Theclasscl_system_transaction_statecontainsseveralusefulutilitymethods:get_in_update_task:returntheflagwhethercurrentcodeisrunningwithnormalworkprocessorinupdateworkprocess get_on_commit:returnflagwhethercurrentcodeiscalledbecauseofapreviousregistrationviaPERFORMONCOMMITandtriggeredbyCOMMITWORK get_sap_luw_key:returncurrentLUWID Ijustuseaverysimplereporttotestthem.FirstIcalltheFMZSQFinanormalway,thencallitviaupdatetask,thenregisteritwithPERFORMONCOMMITandtriggeritviaCOMMITWORK. WRITE:/'Dire

  • 设计模式- 建造者模式(Builder Pattern)

    定义建造者模式(BuilderPattern):将复杂对象的构造与其表示分离,以便相同的构造过程可以创建不同的表示。 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。想象一个角色扮演游戏的角色生成器。最简单的选择是让计算机为您创建角色。但是,如果你想选择角色的细节,比如职业、性别、头发颜色等,那么角色的生成就成了一个循序渐进的过程,当所有的选择都准备好时,这个过程就完成了。C#例子publicclassPeople { privatereadonlystring_profession; privatereadonlystring_name; privatestring_hairType; privatestring_hairColor; publicPeople(Builderbuilder) { this._profession=builder.Profession; this._name=builder.Na

  • 开发工具总结(7)之多年珍藏的Android开发必备网站和工具

    版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/781c1b56bc5b 转载请标明出处:https://www.jianshu.com/p/781c1b56bc5b本文出自AWeiLoveAndroid的博客 【前言】工欲善其事,必先利其器。搞开发多年了,会收藏一些干货网站和工具,辅助开发,提高开发效率。下面一次性分享给大家。喜欢的朋友们点个赞吧。 说明:这些是我收藏的网站,感觉还是不错的,仅仅推荐使用,如果你觉得不好,可以不使用,使用权还是由你们掌握。如果因为不良使用出现的任何纠纷,谁使用谁负责。 一、安卓开发 (1)android以及AndroidStudio开发网站(AndroidStudio、IDE、gradle、模拟器、sdk啥都可以找到) 这些都是可以直接打开的,无需访问外国网站!是不是很爽? AndroidStudio中文社区(官网)AndroidStudio中文社区论坛Google开发者的自频道-优酷视频谷歌公司为中国开发者提供的视频MaterialDesign官方介绍GoogleMaterialDesign的库

  • 勤智数码董事长廖昕:做好政务大数据工作还需“一网一生态”

    数据猿导读能够从大数据中获得全新价值的消息固然令人兴奋,然而,怎样从大数据中挖掘出“真金白银”则是一个现实的挑战。面对巨大的机会,如何真正做好数据汇聚,盘活数据价值?廖昕认为,还需要一张网、一个生态。作者|廖昕本文长度为2000字,建议阅读4分钟本文为数据猿年关策划活动《大数据的2016,我的2016》系列稿件,感谢本文作者勤智数码董事长廖昕先生的投稿。敬请期待春节后的2月16日,由数据猿与中欧商学院、腾讯视频共同举办的高端领袖线下演讲栏目中欧微论坛之《超声波》。大数据时代,数据已经成为了一项蕴含巨大价值的国家资本。微软研究显示,未来十年,数据生产和加工将带来1.6万亿美元的额外价值;2025年大数据将成为33万亿美金新兴产业的基石;中国计算机学会对大数据发展趋势十大预测里,政府大数据将发展迅速,机器学习继续成为智能分析核心技术。高价值数据广泛存在于政府、企业、行业机构、科研院所中,像亟待挖掘的富矿,蕴涵着惊人的商业潜能。“一张网、一个生态”构想的落地开花能够从大数据中获得全新价值的消息固然令人兴奋,然而,怎样从大数据中挖掘出“真金白银”则是一个现实的挑战。面对巨大的机会,如何真正做好

  • 7-9 判断素数 (20分) 本题的目标很简单,就是判断一个给定的正整数是否素数。[通俗易懂]

    大家好,又见面了,我是你们的朋友全栈君。7-9判断素数(20分)本题的目标很简单,就是判断一个给定的正整数是否素数。 输入格式:输入在第一行给出一个正整数N(≤10),随后N行,每行给出一个小于2​31​​的需要判断的正整数。 输出格式:对每个需要判断的正整数,如果它是素数,则在一行中输出Yes,否则输出No。输入样例: 2 11 111 输出样例: Yes No复制#include<iostream> #include<string> #include"math.h" usingnamespacestd; intmain(){ intN,inputNum,flag; cin>>N; while(N--) { flag=0; cin>>inputNum; if(inputNum>1) flag=1; for(inti=2;i<=sqrt(inputNum);i++) if(inputNum%i==0) { flag=0; break;

  • 腾讯云云数据库Redis查询参数模板详情api接口

    1.接口描述接口请求域名:redis.tencentcloudapi.com。 查询参数模板详情。 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DescribeParamTemplateInfo。 Version 是 String 公共参数,本接口取值:2018-04-12。 Region 是 String 公共参数,详见产品支持的地域列表。 TemplateId 是 String 参数模板ID。 3.输出参数 参数名称 类型 描述 TotalCount Integer 实例参数个数 TemplateId String 参数模板ID。 Name String 参数模板名称。 ProductType I

  • docker对数据卷进行还原操作

    转载请注明出处 数据卷容器备份数据后,备份数据查看http://www.cnblogs.com/zhuxiaojie/p/5947138.html   我们可能要把这个备份的数据,还原到另一台的docker容器中,那么要怎么做呢? 首先我们要了解一些基础命令,请查看 http://www.cnblogs.com/zhuxiaojie/p/5947138.html     具体的还原命令如下,需要两个步骤   1:新建一个空的数据卷容器     dockerrun-v/dbdata2--namedbdata2hehe/bin/bash复制   这是一个空的数据卷容器   2:还原数据到数据卷容器中   dockerrun--privileged=true--volumes-fromdbdata2-v/sb:/sbcentostar-xzvf/sb/backup.tar.gz-C/dbdata2复制     --privileged=true 

  • 转:JMeter5的If Controller操作解析

    问题描述 在JMeter中添加了IfController控制器,然后再控制器的表达式输入框中输入了预先构造的为“真”条件,执行Run发现结果树中并没有监控到执行的记录。 问题分析 在最新版JMeter(目前版本:4.0)中,打开IfController的界面,发现Express输入框上方有一段警告类型的提示语,如下:     "Forperformanceitisadvisedtocheck"InterpretConditionasVariableExpression" anduse__jexl3or__groovyevaluatingtotrueorfalseoravariablethatcontainstrueorfalse. ${JMeterThread.last_sample_ok)canbeusedtotestiflastsamplerwassuccessful" 使用建议: 在Expression输入框中,建议将判断条件解释为变量表达式,并使用__jexl3函数或__groovy函数对该变量表达式求值为true/false

  • VIMTUTOR《VIM教程》

    =============================================================================== =   欢  迎  阅  读 《VIM 教 程》 ——   版本1.7   = ===============================================================================    Vim是一个具有很多命令的功能非常强大的编辑器。限于篇幅,在本教程当中    就不详细介绍了。本教程的设计目标是讲述一些必要的基本命令,而掌握好这    些命令,您就能够很容易地将Vim当作一个通用编辑器来使用了。    完成本教程的内容大约需要25-30分钟,取决于您训练的时间。

  • 工程师的思维转变

    这几天浏览论坛看到一个帖子。如醍醐灌顶,解开了很多之前想不明白的问题。 知识体系到思维体系 我之前写过一个《早点建立自己的知识体系》,现在看来原来我只在第一层,更上一层的应该是思维体系的建立。 首先明白一个问题,你工作到底是在追求什么?前几天在公司的调查问卷上,我写了我工作的目的,获取尊重和认同感,创造价值以及获取丰厚的报酬。那么各位在工作的时候是在追求什么?你追求的东西就会指导你的工作实践。 其次我们有没有自己的工作方法论,具体点说,我们有没有形成自己的学习框架和通用能力。第一部分是我们面对新事物、新东西时快速学习的前提,第二部分是我们除了技术以外的软素质比如:学习总结、沟通表达、逻辑思维。 自我驱动,形成核心竞争力 很多新入职场的同学,主动性太差。如果一件事情不归你管,那么如果有一个主动去做,主动承担。你怎么看?有相当一部分同学,大概会这么想:手伸太长了,也太卷了,我只想躺平。或者是这种脏活累活我不想做,跟我没关系。一个组织内的新人想获得信任、建立个人品牌的最好时机就是第一件事或者平时的表现。做事认真一点、积极主动一点、考虑的更深入全面一点,你已经比70-80%的同学好了,这样你就

  • UIActivityIndicatorView的使用

    关于UIActivityIndicatorView,我们一般会用一个背景View来衬托他,将UIActivityIndicatorView放在背景view上,在需要的时候调出这个View。 -(instancetype)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style  typedefNS_ENUM(NSInteger,UIActivityIndicatorViewStyle){   UIActivityIndicatorViewStyleWhiteLarge,  //大号白色   UIActivityIndicatorViewStyleWhite,     //白色    UIActivityIndicatorViewStyleGray__TVOS_PROHIBITED, //灰色 }; 初始化之后,还需要给它一个Frame,但是只有前两个位置

  • PHP关于依赖注入(控制反转)的解释和例子说明

    PHP关于依赖注入(控制反转)的解释和例子说明 发表于2年前(2014-03-2010:12)  阅读(726) | 评论(1) 8人收藏此文章, 我要收藏 赞2 阿里云双11绽放在即1111元红包即刻开抢!»   摘要 自从听到依赖注入这个设计模式,感觉很高大上,无奈楼主的眼光一直局限在国内框架上,也很少去关注设计模式方面的文章,直到某天遇到了laravel后,发现它手册里重点强调了一个名为“依赖注入”和“容器”的概念,但是对于这两个概念,手册里并未做基本的解释,所以楼主只能另外查找相关资料,无奈都是java的,要么就是讲一大堆道理的,没有一个清晰简洁直达本质的文章。幸运的是,当楼主再次接触到phalcon这个框架时,在其手册里发现了一个篇幅专门描述了依赖注入和容器,就把它转了,记录到博文里,以供后来者参考。   目录[-] 在容器中注册服务¶ 原文地址:http://phalcon.5iunix.net/reference/di.html   下面要

  • iOS 提升代码的安全性,可以做哪些措施???

    希望能尽量防止别人反编译你的代码: 目前苹果审核规则可知,苹果官方是不希望你使用代码混淆的。。。如果发现了你用代码混淆,甚至会勒令你修改你的代码,否则下一次审核会直接移除你的app…尤其是跑脚本的那种。我猜想,目的是防止马甲包泛滥,并且苹果不希望你有所隐瞒。。。所以代码要请清清白白 参考审核规则 Guideline2.3.1-Performance Wediscoveredthatyourappcontainshiddenfeatures.Specifically,Itwouldbeappropriatetoremoveallcodeobfuscationandselectormanglingortoexplainindetailthepurposeofitsinclusionbeforeresubmittingforreview.   那么,我们想提高一些代码的安全性,还有哪些手段措施:   1. 数据加密:      1.本地数据数据加密:     &n

  • CF1157D N Problems During K Days

    思路 简单的贪心 序列肯定是由几段公差为1的等差数列组成的,然后之间计算剩下的数字能有多大的和,不够的话整体上升1补上就好了 代码 #include<cstdio> #include<algorithm> #include<cstring> #defineintlonglong usingnamespacestd; intn,k,last=0,a[101000]; intsum(intfirst,inttimes){ return(first+times-1+first)*times/2; } signedmain(){ scanf("%d%d",&n,&k); for(inti=1;i<=k;i++){ intq=last+1,t=k-i+1; intdelta=max(n-sum(q,t),0LL); if(i!=1) q+=min(last-1,delta/t); else q+=delta/t; n-=q; last=q; a[i]=q; } if(n!=0) printf("NO\n"); else{ printf("

  • [CSP 2019]括号树[dp]

    原题:https://www.luogu.com.cn/problem/P5658 好菜啊这么久才把这道签到题补掉.... 考场上只会一个$O(n^2)$暴力,考虑把暴力换成dp 首先一定有一个$dp_i$表示当前位置的答案,显然无法直接转移,考虑还需要知道哪些信息? 还需要记一个$lst_i$表示当前位置')'能匹配到的'('的位置 为了统计答案还需要一个$now_i$表示当前位置向根连续的合法括号串的数量 大概可以了,来考虑一下如何转移,首先一定需要分类讨论 如果是'(',那么似乎没有什么可做的,继承了父亲的答案数组f,然后把$lst_i$设为自己即可 如果是')',且$lst_i==0$,这个括号是没有用处的,继承父亲的答案数组f然后跑就完事了 如果是')',且$lst_i$有值,那么首先f和lst继承以下父亲,然后三个数组都需要有以下转移 $now_i=now[fa[lst_i]]+1$,连续的合法串又多了一个 $f_i=f[fa[i]]+now_i$,答案可以统计出来了 $lst_i=lst[fa[lst_i]]$,待匹配的'('向上方移动一个 1#include<

  • 字符串最小子序列

    链接:https://ac.nowcoder.com/acm/contest/551/D来源:牛客网 时间限制:C/C++1秒,其他语言2秒 空间限制:C/C++524288K,其他语言1048576K 64bitIOFormat:%lld 题目描述 CSL以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助。 给定一个字符串,只含有可打印字符,通过删除若干字符得到新字符串,新字符串必须满足两个条件: 原字符串中出现的字符,新字符串也必须包含。 新字符串中所有的字符均不相同。 新字符串的字典序是满足上面两个条件的最小的字符串。 输入描述: 仅一行,有一个只含有可打印字符的字符串s。   |s|≤105|s|≤105 输出描述: 在一行输出字典序最小的新字符串。复制 示例1 输入 复制 bab复制 输出 复制 ab复制 示例2 输入 复制 baca复制 输出 复制 bac复制 备注: ASCII字符集包含94个可打印字符(0x21-0x7E),不包含空格。题解:拿栈来维护就好了复

  • 介绍 | 通信开发库libComm

      libComm是一个免费的简单的通信库,其中的接口类与函数大都以小写的x打头。 下载 SampleusinglibComm -v1.1ForWinXP libComm-v1.2ForWinXP/Win7  libComm提供三大功能,一是设备查找,二是设备通信,三是辅助通信。其主要的接口类与接口函数如下: 查找类与函数 classXDEVICE_CLASSCxDeviceFind classXDEVICE_CLASSCxDeviceMapFind classXBTH_CLASSCxBthRemoteDeviceFind classXBTH_CLASSCxBthRadioFind classXBTH_CLASSCxBthRadio classXNET_CLASSCxLocalHostIPAddrFind classXNET_CLASSCxAdapterFind classXNET_CLASSCxNetworkHostFind XBTH_APIBOOLBthFindDevice(LPCTSTRlpszRemoteDevName,LPTSTRlpszRadioMacA

相关推荐

推荐阅读