I have a react hook style component in typescript. I'm using office uifabric as ui framework. I want to get the following pattern to work in a "best practice" manner:
- I have a component with an
onClick
event (in my case a CommandBar) - User clicks on the action
- I make an async call to a backend api (the async part is whats causing me trouble here I think, and this is unfortunately a requirement).
- When the async call is complete, or fails. I want to show a MessageBar with information.
- All in all using as little code as possible, react hooks seems to have the ability to produce nice and condence code together with TypeScript. But I'm new to both things so I may be out on a limb here...
Creating a dummy fetch method that is NOT async causes my example code to work as expected. But when I have the async call, something gets lost and I do not get a re-render and visibility of the MessageBar. The api call is made though!
const UserProfile = () => {
const [apiStatusCode, setApiResponseCode] = useState(0);
const [showMessageBar, setShowMessageBar] = useState(false);
const startAsync = () => {
// With await here I get a compiler
// error. Without await, the api call is made but
// the messagebar is never rendered. If the call is not async, things
// work fine.
myAsyncMethod();
};
const toggleMessageBar = (): (() => void) => (): void => setShowMessageBar(!showMessageBar);
const myAsyncMethod = async () => {
try {
const responseData = (await get('some/data'))!.status;
setApiResponseCode(responseData);
toggleMessageBar();
} catch (error) {
console.error(error);
setApiResponseCode(-1);
toggleMessageBar();
}
};
const getItems = () => {
return [
{
key: 'button1',
name: 'Do something',
cacheKey: 'button1', //
onClick: () => startAsync()
}
];
};
return (
<Stack>
<Stack.Item>
<CommandBar
items={getItems()}
/>
</Stack.Item>
{showMessageBar &&
<MessageBar messageBarType={MessageBarType.success} onDismiss={toggleMessageBar()} dismissButtonAriaLabel="Close">
Successfully retrieved info with status code: {apiStatusCode}
</MessageBar>
}
// Other ui parts go here
</Stack>
)
};
export default UserProfile;
Assigning an async method to the onClick event gives compiler error:
Type 'Promise<void>' is not assignable to type 'void'. TS2322
Not awaiting the async call causes react not re-rendering when call is complete.