Open lulusir opened 5 years ago
函数每次执行都更新 current 确实没问题,但是从更加精确的控制角度来讲,是不是这样会更好:
useEffect(() => {
stateRef.current = state;
}, [state]);
let val = 0;
在函数组建作用域外使用可变变量,会导致该组件同时只能使用一个。
@liyuanqiu 嗯,像你这样比对更新的确会更好。
function useRefState(initialState) {
const [state, setState] = useState(initialState);
const stateRef = useRef(null);
useEffect(() => {
stateRef.current = state;
}, [state]);
return [state, setState, stateRef];
}
在函数组建作用域外使用可变变量,会导致该组件同时只能使用一个。
这个是什么意思?
A Button
component:
let sum = 0;
function Button({
name,
}) {
function handleClick() {
sum += 1;
console.log(`Button(${name}) has been clicked for ${sum} times!`);
}
return (
<button
onClick={handleClick}
>
click me!
</button>
);
}
In your app:
function App() {
return (
<Button name="button-1" />
<Button name="button-2" />
);
}
See: https://codesandbox.io/s/w0rjxro1q7 (Open console to see logs)
第一个例子 像这样 setCount(precount => precount + 1); 他拿到的是上一次的count值,他会一直改变count ,虽然定时器里面的count,不会改变,但是页面上的值,会一直跟随者定时器来更新
第二个例子你使用了useRef()
setCount(countRef.current + 1);
你大可不必用函数的方式,因为这种是间接拿到的是count 值
import React, {Fragment, useState, useEffect, useRef, useCallback} from "react";
const useInterval = (callback: any, val: any) => {
const saveCallback = useRef();
useEffect(() => {
saveCallback.current = val
},[val]);
useEffect(() => {
let id = setInterval(() => callback(saveCallback.current), 1000);
return () => clearInterval(id);
}, []);
};
function App() {
const [count, setCount] = useState(0);
useInterval((val: number) => {
setCount(val + 1);
}, count);
return (
<Fragment>
<p> count: {count} </p>
</Fragment>
);
}
export default App
定时器没有获取到最新的state
定时器中的count 会一直会0, 因为定时器一直引用着旧的变量。 demo
解决方法:
用一个变量来保存引用值,在每次react执行时更新。既然使用hook,我们可以用useRef来保存这个引用 demo
或者在外层作用域保存这个变量(注意这里会出现多个组件引用同一个变量的问题:参考3楼的demo)
我们可以把这个功能包装成hooks,demo
参考 https://github.com/facebook/react/issues/14543