我正在尝试创建一个 promisify 样式的钩子,想法是最终将它与 Redux Toolkit 一起使用,以允许使用新的 React 19use
钩子。
以下是这个东西的工作原理:
function usePromise(input: {
isLoading: true,
data: null
} | {
isLoading: false,
data: string;
}) {
// Store the resolve function in a ref
const resRef = useRef<(data: string) => void>(null);
// Create a new promise
// Store the resolve function in the ref
const promiseRef = useRef(
new Promise((res) => {
resRef.current = res;
//res("xxx") // 👈 this will resolve though
})
);
// When input changes, if there is data, resolve the promise
useEffect(() => {
if (!input.isLoading) {
resRef.current?.(input.data);
}
}, [input]);
// Return the promise
return promiseRef.current;
}
用法如下:
export function MyComponent() {
const [value, setValue] = useState<null | string>(null);
const prom = usePromise(value ? {
isLoading: false,
data: value
} : {
isLoading: true,
data: null
});
prom.then((v) => alert(v))
return <div >
<button onClick={() => setValue("123")}>Click me</button>
</div>
}
在这里,我期望当我们点击按钮时,承诺会得到解决,我们会看到警报。然而,事实并非如此。
这里发生了什么事?
我在这里复制了此问题:https ://github.com/dwjohnston/react-promise-issue
您的问题是每次运行钩子时,您都会创建一个新的承诺,并将其设置
resRef.current
为最后一个承诺的解析器函数。但是,只有传递给useRef
钩子的第一个承诺才会存储在 中promiseRef.current
。为了解决此问题,请避免重新创建承诺:
或者,使用通过回调初始化的状态: