react项目中遇到的几个问题
react项目中遇到的几个问题
前言
由于我之前有过react经验,同事之前做react项目时问了我一些问题,其中几个问题虽然常见,但时间长了还是容易忘记,这里简单总结一下
问题一:
如何保证定时器(setTimeout与setInterval)每次执行与下一次执行都保证相同的间隔时间,不管前一次运行了多长时间
场景:
例如需要每间隔1秒执行一次请求的发起与响应,不管第一次发起请求到响应花费了多久,例如200ms,下一次请求一定与第一次完成间隔1000ms(即第二次请求在1200ms时发起,而不是800ms时发起),以此类推
思路一:
考虑到重新计时,应该可以通过防抖来实现,上网查阅后确实可行,还提供了思路二
之前:
useEffect(()=>{
const timer=setInterval(()=>{
Ajax();//代表发起异步操作
},1000)
return ()=>{clearInterval(timer)};
},[])
修改之后:
useEffect(()=>{
debounce(Ajax,1000);
},[])
//防抖函数
const debounce = function (fn,delay){
let timer;//声明计时器
return function(){
let _this = this;
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(_this);
},delay)
}
}
思路二:
通过setTimeout递归实现
解释:
可以通过 setTimeout(fn , 0)来理解,setTimeout可以将代码推迟到指定时间执行,这样,当确保第一次执行完毕后,再推迟到1000ms之后执行第二次
之前:
useEffect(()=>{
const timer=setInterval(()=>{
Ajax();//代表发起异步操作
},1000)
return ()=>{clearInterval(timer)};
},[])
修改之后:
useEffect(()=>{
let timer = setTimeout(function Ajax(){
//…
timer = setTimeout(Ajax,1000);
},1000)
},[])
问题二:
react-hooks中的useState是一个异步的操作,如何实时获取到更新后的新的State状态呢?
思路一:
通过useEffect实现
useEffect(()=>{
setState(state);
},[state]);
思路二:
通过useRef实现
useRef返回一个可变的ref对象,其.current属性被初始化为传入的参数(initialValue)
返回的ref对象在组件的整个生命周期内都保持不变
const [state,setState]=useState('')
const modelRef = useRef(null);
useEffect(()=>{
//每次更新都把值赋给modelRef
modelRef.current = state;
},[state]);//保证state改变时,触发useEffect
function handleChange(newState){
setState(newState);//state改变,触发useEffect
setTimeout(getState, 0);//设置一个0ms延迟很重要
}
function getState(){
console.log(modelRef.current);//获取到最新值
}
同时获取多个最新值
const changeSelectRef = useRef({
"status": "",
"modelStatus": "",
"keyWord": ""
});
useEffect(()=>{
changeSelectRef.current = {
"status": status,
"modelStatus": modelStatus,
"keyWord": keyWord
};
}, [status, modelStatus, keyWord]);
参考:
http://www.jsphp.net/js/show-9-157-1.html
https://javascript.ruanyifeng.com/advanced/timer.html
https://blog.csdn.net/hl971115/article/details/104564923
https://segmentfault.com/a/1190000020948922
https://segmentfault.com/a/1190000039365818