Estou tentando criar um hook no estilo promisify. A ideia é usá-lo com o Redux Toolkit para permitir o uso do novo use
hook do React 19.
Aqui está a essência de como isso funcionaria:
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;
}
Com uso como:
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>
}
Aqui, eu esperaria que, quando clicarmos no botão, a promessa fosse resolvida e víssemos o alerta. No entanto, isso não acontece.
O que está acontecendo aqui?
Tenho uma reprodução para esta edição aqui: https://github.com/dwjohnston/react-promise-issue
Seu problema é que você está criando uma nova promessa toda vez que o hook é executado, configurando
resRef.current
a função resolver daquela última promessa. No entanto, apenas a primeira promessa que é passada para ouseRef
hook é armazenada empromiseRef.current
.Para corrigir isso, evite recriar a promessa :
Como alternativa, use um estado que é inicializado com um retorno de chamada :