React Hooks 钩子函数错误用法,你还在犯这些错误吗

news2024/9/23 23:31:25

React Hooks 常见错误

前言

本片文章主要是在写react hooks的时候,遇到的常见错误的写法,和错误。也是一个对只是的巩固和总结。


错误一

上代码:正确写法

function TestReactHooksError() {
  const [test, setTest] = useState('test');
  useEffect(() => {
    if(test) {
      console.log(test)
    }
  }, [test]);
  return (
    <div>
      <button onClick={()=>setTest(test + 1)}>{test}click</button>
    </div>
  );
}
export default TestReactHooksError

解析:
功能,点击按钮,按钮文案改动,并且控制台打印文案结果。
稍作改动:

function TestReactHooksError() {
  const [test, setTest] = useState('test');
  if (test) {
    useEffect(() => {
      console.log(test)
    }, [test]);
  }
  return (
    <div>
      <button onClick={() => setTest(test + 1)}>{test}click</button>
    </div>
  );
}
export default TestReactHooksError

可以看到报错了:
在这里插入图片描述
搜狗翻译:
React钩子“useEffect”被有条件地调用。React挂钩必须在每个组件渲染中以完全相同的顺序调用
正常翻译:
就是钩子函数必须按顺序执行,因为底层是按顺序执行的,所以如果加入判断的话,可能有不可预知的错误。


错误二

上代码:正确写法

function TestReactHooksError() {
  const [test, setTest] = useState([1, 2, 3, 4, 5]);
  useEffect(() => {
    consoleLog()
  }, []);
  const consoleLog = (value) => {
    for (let i = 0, len = test.length; i < len; i++) {
      console.log(test[i])
    }
  }
  return (
    <div>
      {
        test.map((item) => {
          return <span key={item}>{item}</span>
        })
      }
    </div>
  );
}
export default TestReactHooksError

解析:
功能,渲染列表,并且控制台打印结果。
稍作改动:

function TestReactHooksError() {
  const [test, setTest] = useState([1,2,3,4,5]);
  for (let i=0, len = test.length; i < len; i++) {
    useEffect(() => {
      console.log(test[i])
    }, [test[i]]);
  }
  
  return (
    <div>
      {
        test.map((item)=>{
          return <span key={item}>{item}</span>
        })
      }
    </div>
  );
}
export default TestReactHooksError

报错:
在这里插入图片描述
可以看到结果都正常打印了,但是报错了。
搜狗翻译:
React挂钩“useEffect”可以执行多次。可能是因为它是在循环中调用的。React挂钩必须在每个组件渲染中以完全相同的顺序调用
正常翻译:
不能在循环中使用hooks,因为还是可能会导致执行顺序错误,导致结果错误。


错误三

上代码: 正确写法

function TestReactHooksError() {
  const [testState, setTestState] = useState('testState')
  const clickState = () => {
    console.log(testState)
  }
  return (
    <div>
      <button onClick={()=>clickState()}>click</button>
    </div>
  );
}
export default TestReactHooksError

解析:
功能,点击按钮控制台打印结果。
稍作改动:

function TestReactHooksError() {
  const clickState = () => {
    const [testState, setTestState] = useState('testState')
    console.log(testState)
  }
  return (
    <div>
      <button onClick={()=>clickState()}>click</button>
    </div>
  );
}
export default TestReactHooksError

报错:
在这里插入图片描述
搜狗翻译:
React挂钩“useState”在函数“clickState”中调用,该函数既不是React函数组件,也不是自定义React挂钩函数。React组件名称必须以大写字母开头。React挂钩名称必须以单词“use”开头
正常翻译:
这个翻译的很明白,就是不能在普通函数中使用,因为react不会理解它是一个组件或者是自定义hooks。


错误四

上代码: 错误写法

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      testState: 'testState',
    };
  }

  useEffect(() => {
    console.log(this.state.testState)
  }, [this.state.testState]);

  render() {
    return (
      <div>
        <p>You clicked {this.state.testState} times</p>
        <button onClick={() => this.setState({ testState: this.state.testState + 1 })}>
          Click
        </button>
      </div>
    );
  }
}

报错:
在这里插入图片描述
报错语法格式错误。所以不能混合使用


错误五

正确的写法:

function TestReactHooksError() {
  const [testState, setTestState] = useState('testState')
  function clickState() {
    console.log(testState)
  }
  return (
    <div>
      <button onClick={() => setTestState(testState + 1)}>{testState}</button>
      <button onClick={() => clickState()}>click</button>
    </div>
  );
}
export default TestReactHooksError

稍作修改:

function TestReactHooksError() {
  const [testState, setTestState] = useState('testState')
  function clickState() {
    console.log(testState)
  }
  return (
    <div>
      <button onClick={() => setTestState(testState + 1)}>{testState}</button>
      <button onClick={clickState}>click</button>
    </div>
  );
}
export default TestReactHooksError

在 JSX 的事件处理程序中调用函数时,应该传递函数本身而不是函数的返回值。改为 onClick={() => handleClick()} 或者将 handleClick 函数定义在组件外部并将其作为 prop 传递给组件。由于当前的写法每次渲染都会创建一个新的函数和事件处理程序,因此会导致浪费和性能问题。
注意:

当然在最新的版本中不会有这个问题因为,React 已经对函数事件处理程序进行了自动绑定,所以在最新版本中不会出现这个问题。这是因为最新版本的 React 使用了异步渲染机制,将多次渲染时创建的函数缓存起来进行重用,从而避免了性能问题。


错误六

使用useEffect时没有传入依赖项,这可能会导致无限制地执行useEffect,当然如果你就是为了重复执行可以跳过这个。
正确写法:

function TestReactHooksError() {
  const [test, setTest] = useState('test');
  useEffect(() => {
    console.log(test)
  }, [test]);
  return (
    <div>
      <button onClick={()=>setTest(test + 1)}>{test}click</button>
    </div>
  );
}
export default TestReactHooksError

稍作修改:

function TestReactHooksError() {
  const [test, setTest] = useState('test');
  useEffect(() => {
    console.log(test)
  });
  return (
    <div>
      <button onClick={()=>setTest(test + 1)}>{test}click</button>
    </div>
  );
}
export default TestReactHooksError

修改之后,如果之后再加入其他按钮渲染数据,当其他数据变化时,还是会执行useEffect,所以需要正确的添加,依赖项。


错误七

定时器
上代码:正确的写法
分别使用setTimeout和setInterval

function TestReactHooksError() {
  const [timer, setTimer] = useState(0);
  const [timerS, setTimerS] = useState(0);
  useEffect(() => {
    setTimeout(() => {
      setTimer(timer + 1)
    }, 1000)
  }, [timer]);
  useEffect(() => {
    setInterval(() => {
      setTimerS(timerS => timerS + 1)
    }, 1000)
  }, []);
  return (
    <div>
      {timer}-{timerS}
    </div>
  );
}
export default TestReactHooksError

但是这样写有一个问题,如果仔细看页面计时显示会发现两个时间有偏差。setTimeout会慢一些,但是这也不难分析,因为setTimeout 和 setInterval 的执行方式是不同的。setTimeout 在每次计时器更新时都会重新创建一个新的计时器,而 setInterval 只会在组件挂载时创建一个计时器。因此,setInterval 的计时器会一直运行,而 setTimeout 的计时器则会受到上一个计时器执行时间的影响,可能会出现延迟。另外,由于 setTimeout 是在依赖数组中的 timer 更新时执行的,当 timer 发生变化时,会重新创建一个新的计时器,这可能会导致计时器的执行时间出现偏差。
说简单点就是,setInterval 每次只是在设定的时间后马上执行,而setTimeout需要依赖数据变化并且每次都重新创建,所以会慢一些

稍作修改
错误的写法:

useEffect(() => {
  setInterval(() => {
    setTimerS(timerS + 1)
    console.log(timerS)
  }, 1000)
}, [timerS]);

可以看到页面显示抽搐的时间
在这里插入图片描述

总结

先这么多文章还会更新。。。
如有问题欢迎指出,感谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/464665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读:PVO: Panoptic Visual Odometry

全景视觉里程计、同时做全景分割和视觉里程计 连接&#xff1a;PVO: Panoptic Visual Odometry 0.Abstract 我们提出了一种新的全景视觉里程计框架PVO&#xff0c;以实现对场景运动、几何和全景分割信息的更全面的建模。我们将视觉里程计(VO)和视频全景分割(VPS)在一个统一的…

【hello Linux】进程间通信——匿名管道

目录 前言&#xff1a; 总结下上述的内容&#xff1a; 1. 进程间通信目的 2. 进程间通信的分类 1. 匿名管道 2. 匿名管道的使用 1. 匿名管道的创建 2. 使用匿名管道进行父子间通信 Linux&#x1f337; 前言&#xff1a; 进程具有独立性&#xff0c;拥有独立的数据、代码及其他…

人工智能时代来临,殊不知低代码早已出手

科普一下人工智能的等级划分&#xff0c;按照实力&#xff0c;人工智能可以分为弱人工智能(Artificial Narrow Intelligence&#xff0c;简称ANI)、强人工智能(Artificial General Intelligence简称AGI)、超人工智能(Artificial Superintelligence简称ASI)三个等级。 弱人工智能…

Windows下 批量重命名文件【bat实现】

目录 前言 一、Windows简单实现重命名 二、使用命令行和Excel实现重命名 前言 在实际应用中&#xff0c;我们经常会遇到将指定文件夹下的文件重命名&#xff0c;以便程序读写。 本文介绍了两种方式&#xff0c;都是在Windows系统中自带的重命名方式。 一、Windows简单实现…

面试题目 002

分享一位读者面试美团 java 岗位的面经。主要在考察 javamysql 算法题目 最长回文串 根据前序中序恢复二叉树 说一说 MySQL 的索引 MySQL 的索引是一种存储数据结构&#xff0c; 按照数据结构划分&#xff0c;MySQL 可以分为 B 树索引、Hash 索引、全文索引 按照 B 树的叶子…

Windows云主机崩溃了怎么办?

​  无法避免服务器崩溃已不是什么秘密&#xff0c;无论选择Windows 云主机还是 Linux 云主机。但不可否认的是&#xff0c;任何错误都可能给企业带来灾难性的后果。该怎么办?持续监控服务器是可能的解决方案之一。即便如此&#xff0c;如果服务器已经处于关闭阶段&#xff…

机器学习实战教程(十):逻辑回归

概述 逻辑回归&#xff08;Logistic Regression&#xff09;是一种用于解决二分类或多分类问题的统计学习方法。它以自变量线性组合的形式进行建模&#xff0c;并使用Sigmoid函数将结果映射到[0, 1]的值域内&#xff0c;表示样本属于某个类别的概率。 Logistic Regression是最…

6个好用的企业管理软件推荐

企业管理软件的范围很广&#xff0c;财务、人力、客户关系管理、ERP、客户体验管理等等。国内来看&#xff0c;有些企业管理软件产品能覆盖企业数字化所有部分&#xff0c;在每个领域&#xff0c;也有很突出的头部厂商&#xff0c;产品功能和服务都大幅领先于竞对&#xff0c;我…

Redis学习笔记大全

文章目录 1、redis概述和安装1.1、安装redis1.2、启动redis方式1&#xff1a;前台启动&#xff08;不推荐&#xff09;方式2&#xff1a;后端启动&#xff08;推荐&#xff09; 1.3、关闭redis1.4、进入redis命令窗口1.5、redis命令大全1.6、redis介绍相关知识 2、redis 5大数据…

PyTorch实战3:天气识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营-第P3周&#xff1a;天气识别&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 目录 一、前期准备1、导入数据2、transforms.Compose详…

JavaWeb+JSP内置对象+Session+Cookie+ 过滤器Filter+ 监听器Listener(超详细)

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;老茶icon &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;计…

从 Milvus 2.2 到 2.2.6,我们是如何持续稳定升级的

最近&#xff0c;Milvus 发布了 2.2.6 版本&#xff0c;在修复了一些 bug 后&#xff0c;Milvus 变得越发稳定。 事实上&#xff0c;自 Milvus 升级至 2.X 版本以来&#xff0c;我们一直在努力改进及优化&#xff0c;推出了诸如从文件中批量导入数据、基于磁盘的近似最近邻&…

通过ppt制作圆形图标及自定义形状图形制作

今天做PPT时&#xff0c;需要一个圆形的截图&#xff0c;日常截图都是方形的&#xff0c;能不能把截图裁剪为一个圆形呢&#xff1f;于时从网上找了一下&#xff0c;发现还真有。 制作工具&#xff1a;PPT 制作步骤&#xff1a; 1、准备图片 将截图或图片插入PPT中 2、在…

(04)基础强化:接口,类型转换cast/convert,异常处理,传参params/ref/out,判断同一对象

一、复习 1、New的截断是指什么&#xff1f; new除了新开空间创建初始化对象外&#xff0c;还有一个隐藏父类同名方法的作用。 当子类想要隐藏父类同名的方法时用new&#xff0c;用了new后父类同名方法将到此为止&#xff0c;后面 继承的…

electron+vue3全家桶+vite项目搭建【15】vue3+sass实现多主题一键切换,支持electron多窗口同步更新

文章目录 引入实现效果展示实现思路整理实现步骤1.定义全局主题样式变量2.定义主题模板3.封装颜色工具类4.初始化主题色5.主进程监听颜色修改6.补充主题状态管理7.主题一键切换组件8.测试案例 引入 我们之前在这篇文章中集成了 sass&#xff0c;接下来我们结合sass的变量定义&…

银行数字化转型导师坚鹏:宏观经济形势分析与银行发展模式创新

宏观经济形势分析与银行发展模式创新 课程背景&#xff1a; 很多学员存在以下问题&#xff1a; 不知道我国目前的宏观经济形势&#xff1f; 不清楚宏观环境对我国经济的影响&#xff1f; 不知道银行未来主要的发展模式&#xff1f; 课程特色&#xff1a; 精彩解读宏…

最新:机器学习在生态、环境经济学中的实践技术应用及论文写作

查看原文>>>最新&#xff1a;机器学习在生态、环境经济学中的实践技术应用及论文写作 目录 专题一、理论基础与软件介绍 专题二、数据的获取与整理 专题三、常用评价方法与相关软件详细教学&#xff08;案例详解&#xff09; 专题四、写作要点与案例的讲解 近年来…

Redis数据库常用语句

Redis数据库常用语句 前言1. 键(Key)的基本操作1.1 增加新的键值对1.2 访问键的值1.3 修改键值对1.4 键值对的删除1.5 判断键值对是否存在1.6 获取所有键1.7 删除所有的键&#xff1a; 2. Redis 中的列表2.1 列表加入新元素2.2 获取列表长度2.3 获取指定下标的元素2.4 获取指定…

Android App 架构 面试专题,你可能会被问到的 20 个问题

iveData 是否已经被弃用? 没有被弃用。在可以预见的未来也没有废弃的计划。 LiveData 可以使用简单的方式获取一个易于观察、状态安全的对象。虽然其缺少一些丰富的操作符&#xff0c;但是对于一些简单的 UI 业务场景已经足够。 Flow 有 LiveData 相同的功能&#xff0c;其…

1.栈的介绍-C语言调用函数(二)

1.栈的介绍-C语言调用函数&#xff08;一&#xff09;_双层小牛堡的博客-CSDN博客 接着上面 函数调用的约定 在栈帧中 主要的是主调函数如何存入实参 让被调用函数能够访问 这种是通过函数见的调用规定来规范的 并且 调用规定还规范了 函数执行完后应该由主函数实现 清除参…