使用 React Hook 获取最新的状态值?
Getting latest state value with React Hook?
尝试将 React Hook 与功能组件一起使用,但 运行 在这种情况下需要获取最新值,我认为使用 class 组件你可以依靠 this.state.foo
成为最新值,但不确定 React Hook 是否可行。
用例
UI 有一个切换开关,有两种状态 - A 和 B,当用户切换到 A 时,我们进行 ajax 调用以获取 A 的数据并显示在 UI, B 也一样.
我使用 useEffect 的代码
function (props) {
const [myState, setMyState] = useState('A')
const [myText, setMyText] = useState()
useEffect(()=>{
ajaxCall(myState).then((data)=>{
setMyText(data)
})
}, [myState])
return <div>{myText}</div>
}
这通常有效,但并非总是有效,ajax 调用需要几秒钟才能完成,用户可以非常快速地切换开关,我们 运行 遇到如下问题:
用户切换到 A,ajax 调用尝试获取 A 的数据。
Ajax 对 A 的调用尚未返回,用户切换到 B,进行新的 Ajax 调用并很快取回数据并为 B 更新 myText
。
10 秒后 ajax 最终调用 A returned 并更新 A 的 myText
。
现在您看到了问题 - 用户选择了 B 但 UI 正在为 A 呈现 myText
。
解决方案
一旦ajax调用return,在设置myText
之前,检查myState
的最新值,如果它已经改变,那么我们不't更新myText
向 useEffect
添加清理方法以中止之前的 ajax 调用(如果尚未完成)。
我不知道 React Hook 是否可以使用解决方案 1,所以似乎首选方法是解决方案 2?
您可以添加一个不会中止 ajax 调用的清理方法,而只是告诉您的 useEffect
挂钩该值不再是当前值,然后忽略 setText
如果 return 值:
useEffect(() => {
let isCurrent = true;
ajaxCall(myState).then(data => {
if (isCurrent) {
setText(data);
}
})
return () => {
isCurrent = false;
}
}, [myState]);
尝试将 React Hook 与功能组件一起使用,但 运行 在这种情况下需要获取最新值,我认为使用 class 组件你可以依靠 this.state.foo
成为最新值,但不确定 React Hook 是否可行。
用例
UI 有一个切换开关,有两种状态 - A 和 B,当用户切换到 A 时,我们进行 ajax 调用以获取 A 的数据并显示在 UI, B 也一样.
我使用 useEffect 的代码
function (props) {
const [myState, setMyState] = useState('A')
const [myText, setMyText] = useState()
useEffect(()=>{
ajaxCall(myState).then((data)=>{
setMyText(data)
})
}, [myState])
return <div>{myText}</div>
}
这通常有效,但并非总是有效,ajax 调用需要几秒钟才能完成,用户可以非常快速地切换开关,我们 运行 遇到如下问题:
用户切换到 A,ajax 调用尝试获取 A 的数据。
Ajax 对 A 的调用尚未返回,用户切换到 B,进行新的 Ajax 调用并很快取回数据并为 B 更新 myText
。
10 秒后 ajax 最终调用 A returned 并更新 A 的 myText
。
现在您看到了问题 - 用户选择了 B 但 UI 正在为 A 呈现 myText
。
解决方案
一旦ajax调用return,在设置
myText
之前,检查myState
的最新值,如果它已经改变,那么我们不't更新myText
向
useEffect
添加清理方法以中止之前的 ajax 调用(如果尚未完成)。
我不知道 React Hook 是否可以使用解决方案 1,所以似乎首选方法是解决方案 2?
您可以添加一个不会中止 ajax 调用的清理方法,而只是告诉您的 useEffect
挂钩该值不再是当前值,然后忽略 setText
如果 return 值:
useEffect(() => {
let isCurrent = true;
ajaxCall(myState).then(data => {
if (isCurrent) {
setText(data);
}
})
return () => {
isCurrent = false;
}
}, [myState]);