当前位置: 首页 > news >正文

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

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.lryc.cn/news/63232.html

相关文章:

  • tpm2-tools源码分析之tpm2_evictcontrol.c(1)
  • SpringCloud_OpenFeign服务调用和Resilience4J断路器
  • 【C++】switch 语句
  • 【Database-06】Centos 9 安装docker版的Oceanbase
  • TiDB Operator 和 Operator Dashboard
  • 计算机网络闲谈01——QUIC协议
  • 楼层滚动效果(超级简单,易懂)
  • FPGA、 CPU、GPU、ASIC区别
  • ChatGPT 之父承认 GPT-5 并不存在,为什么 OpenAI 总是这么实诚?|万字详述
  • 华为交换机配置telnet登录图文教程
  • Linux:网络基础1
  • Matlab对日期变量和时间变量的管理
  • js字符串 常用方法 并带详细讲解
  • Oracle_Audit_审计
  • python算法中的深度学习算法之生成对抗网络(详解)
  • 【VM服务管家】VM4.0软件使用_1.2 工具类
  • Android系统架构
  • 零基础想成为黑客,只需要四步
  • ChatGPT研究报告:AIGC带来新一轮范式转移
  • 自助式数据分析平台:jvs数据智仓-统计报表的使用条件及界面介绍
  • php连接sqlserver
  • Android 9.0 原生SystemUI下拉通知栏UI背景设置为圆角背景的定制(一)
  • vCenter(PSC)正常更改或重置administrator@vsphere.local用户的密码方法
  • 【五一创作】Java 反射
  • 常见元件、封装、尺寸、表面处理等
  • 作为一名8年测试工程师,因为偷偷接私活被····
  • 前端面试八股文
  • [创新工具和方法论]-02- DOE实验设计步骤
  • XXL-JOB分布式任务调度平台搭建以及和SpringBoot整合应用
  • 【LeetCode】236. 二叉树的最近公共祖先