使用钩子在 React 组件的多次调用之间共享可变状态
Share mutable state between multiple invocations of a React component with hooks
我想创建一个 withPromise
,其工作方式如下:
import {useState, withEffect} from "react";
function usePromise(promise, default=null) {
// This state variable will hold the value of our promise.
// We allow the user to pass in a default value that'l be returned
// as long as the promise hasn't been resolved.
let value, setValue = useState(default);
// Ensure that this is only re-run when the promise changes.
withEffect(() => {
promise.then(setValue)
}, [promise])
return value;
}
如果 promise 参数永远不会改变,这会很好地工作,但我希望它能够适应以防传入新的 promise,因为在这一点上,它可能会导致竞争条件。
promise1
传递给 usePromise
promise2
传递给 usePromis-e
promise2
已解决,设置值为value2
promise1
已解决,设置值为value1
在这一系列事件中,新承诺的值被稍后解决的旧承诺的值覆盖。
但是由于 promise 是不可取消的,我没有找到一种方法来检查 promise 的回调是否在等待解决时是否传入了新的 promise。
有什么办法可以做到这一点吗?
useEffect 可以return 一个用于拆卸逻辑的函数。虽然您无法取消承诺,但您可以设置一个标志,然后在承诺解决时检查该标志以中止回调。例如,类似于以下内容:
function usePromise(promise, default=null) {
let [value, setValue] = useState(default);
useEffect(() => {
let cancelled = false;
promise.then((result) => {
if (!cancelled) {
setValue(result);
}
})
return () => cancelled = true;
}, [promise])
return value;
}
我想创建一个 withPromise
,其工作方式如下:
import {useState, withEffect} from "react";
function usePromise(promise, default=null) {
// This state variable will hold the value of our promise.
// We allow the user to pass in a default value that'l be returned
// as long as the promise hasn't been resolved.
let value, setValue = useState(default);
// Ensure that this is only re-run when the promise changes.
withEffect(() => {
promise.then(setValue)
}, [promise])
return value;
}
如果 promise 参数永远不会改变,这会很好地工作,但我希望它能够适应以防传入新的 promise,因为在这一点上,它可能会导致竞争条件。
promise1
传递给usePromise
promise2
传递给usePromis-e
promise2
已解决,设置值为value2
promise1
已解决,设置值为value1
在这一系列事件中,新承诺的值被稍后解决的旧承诺的值覆盖。
但是由于 promise 是不可取消的,我没有找到一种方法来检查 promise 的回调是否在等待解决时是否传入了新的 promise。
有什么办法可以做到这一点吗?
useEffect 可以return 一个用于拆卸逻辑的函数。虽然您无法取消承诺,但您可以设置一个标志,然后在承诺解决时检查该标志以中止回调。例如,类似于以下内容:
function usePromise(promise, default=null) {
let [value, setValue] = useState(default);
useEffect(() => {
let cancelled = false;
promise.then((result) => {
if (!cancelled) {
setValue(result);
}
})
return () => cancelled = true;
}, [promise])
return value;
}