I have a Button which is disabled depending on an isSubmitDisabled
function which is defined as async
because it has an async
part.
<Button type="button" disabled={isSubmitDisabled()}>Submit</Button>
const isSubmitDisabled = async () => {
let result1 = await validatePart1(..);
//...
return finalResult ? true : false;
}
The validation works, but I can't use the prop expression syntax above for disabled=
.
If I do disabled={isSubmitDisabled()}>
error: Type 'true | Promise' is not assignable to type 'boolean | undefined'. Type 'Promise' is not assignable to type 'boolean | undefined'.ts(2322)
If I do disabled={await isSubmitDisabled()}>
error: 'await' expressions are only allowed within async functions and at the top levels of modules
If I do a wrapper function per this example:
disabled = {
(async () => {
await isSubmitDisabled()
})()
}
error: Type 'Promise' is not assignable to type 'boolean | undefined'.
You can't synchronously get a value from an asynchronous operation.
Use a state value to drive the UI, and update that state value from the asynchronous operation. For example, consider a simple boolean state:
const [disableSubmit, setDisableSubmit] = useState(true);
Use that value to drive the button:
<Button type="button" disabled={disableSubmit}>Submit</Button>
Then you can update that state value from the asynchronous operation. When/where that operation is invoked is up to you, in this case I'm just adding it to a useEffect
which is executed once when the component first loads:
useEffect(() => {
(async () => {
let result1 = await validatePart1(..);
//...
setDisableSubmit(finalResult ? true : false);
})();
}, []);
Depending on the structure of what you're building, you may invoke this operation at a different time or even at multiple times. But however you structure it, the point is to use state as an intermediary for asynchronous values.