解决React执行两次render的问题
原因
最近的react版本,dev模式下render使用的是strict mode,strict mode的通过两次调用constructor和render函数来更好的检测不符合预期的side effects
下列函数会执行两次
- 类组件的constructor,render和shouldComponentUpdate方法
- 类组建的静态方法getDerivedStateFromProps
- 函数组件方法体
- 状态更新函数(setState的第一个参数)
- 传入useState,useMemo或useReducer的函数
在production
环境下不会这样,所以不用担心
【BUG:本地数据与显示数据不一致】
设置两次数据,第一次从 undefined 到 [ ],第二次再从 [ ] 到 [数据]
【解决方法一】
- 使用计数监听配合
useEffec
防止设置两次数据- 只有>1执行代码,第一次设置无作用,只保留第二次设置
import React, { useRef } from 'react'
import { useEffect, useState } from 'react';
const A = () => {
const [data,setData] = useState(0)
const count = useRef(0) //存放自定义属性,默认值为0
const add = () => {
setData(data + 1)
//setData会触发两次渲染,两次data数据并没有合并,只把首次数据(0)传给了localStorage,所以本地数据与实时数据不一致
// window.localStorage.setItem('value',data)
}
useEffect(() => { //出生/更新:每次计算渲染
count.current += 1
})
useEffect(() => { //只有>1执行代码
if (count.current > 1) {
window.localStorage.setItem('value',data)
}
}, [data])
return (
<>
{data}
<button onClick={add}>+1</button>
</>
)
}
优化计数代码
封装自定义Hook
新建
src/hooks
目录- 新建
useUpdate
文件
- 新建
封装
useUpdate
函数引入
React/useRef/useEffect
import React, { useRef,useEffect } from 'react'
声明
useUpdate
函数const useUpdate = (fn,deps) => {
const count = useRef(0)
useEffect(() => {
count.current += 1
})
useEffect(() => {
if (count.current > 1) {
fn()
}
}, deps)
}
export {useUpdate}
重构组件
- 引入
useUpdate
import { useUpdate } from '../hooks/useUpdate';
- 使用
useUpdate
函数useUpdate(() => {
window.localStorage.setItem('value',data)
}, [data]) - 组件完整代码
import React from 'react'
import {useState } from 'react';
import { useUpdate } from '../hooks/useUpdate';
const A = () => {
const [data, setData] = useState(0)
const add = () => {
setData(data + 1)
}
useUpdate(() => {
window.localStorage.setItem('value',data)
}, [data])
return (
<>
{data}
<button onClick={add}>+1</button>
</>
)
}
export default A
【解决方法二】
setTimeout定时器
useEffect(() => {
const timeout = setTimeout(() =>
verifyIsLogin(), 300);
return () => clearTimeout(timeout);
async function verifyIsLogin() {
};
// verifyIsLogin();
}, []);
链接
react hooks useEffect 执行两次解决方案 javascript - useEffect 调用了两次 解决useEffect重复调用问题 React + Hooks中组件重复渲染的问题