react-use#useAsyncFn TypeScript Examples
The following examples show how to use
react-use#useAsyncFn.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ConvertExternalLinkView.tsx From joplin-utils with MIT License | 6 votes |
MatchNoteList: React.FC<MatchNoteListProps> = (props) => {
const [onConvertNoteState, onConvertNote] = useAsyncFn(props.onConvertNote)
return (
<List
dataSource={props.url.matchNotes}
className={css.sub2}
loading={onConvertNoteState.loading}
renderItem={(matchNote) => (
<List.Item key={matchNote.id}>
<Space>
<Typography.Text>{matchNote.title}</Typography.Text>
<Button onClick={() => onConvertNote(matchNote)}>{i18n.t('convertExternalLink.action.convert')}</Button>
</Space>
</List.Item>
)}
/>
)
}
Example #2
Source File: DashboardPicker.tsx From grafana-chinese with Apache License 2.0 | 6 votes |
DashboardPicker: FC<Props> = ({
onSelected,
currentDashboard,
size = 'md',
isClearable = false,
invalid,
disabled,
}) => {
const debouncedSearch = debounce(getDashboards, 300, {
leading: true,
trailing: true,
});
const [state, searchDashboards] = useAsyncFn(debouncedSearch, []);
return (
<Forms.AsyncSelect
size={size}
isLoading={state.loading}
isClearable={isClearable}
defaultOptions={true}
loadOptions={searchDashboards}
onChange={onSelected}
placeholder="Select dashboard"
noOptionsMessage="No dashboards found"
value={currentDashboard}
invalid={invalid}
disabled={disabled}
/>
);
}
Example #3
Source File: CheckParentNotebookView.tsx From joplin-utils with MIT License | 5 votes |
CheckParentNotebookView: React.FC = () => {
const [list, setList] = useState<
Pick<NoteProperties, 'id' | 'title' | 'parent_id'>[]
>([])
const [onCheckState, onCheck] = useAsyncFn(async () => {
const list = await checkParentNotebookService.check()
console.log('list: ', list)
setList(list)
})
async function onRemove(id: string) {
await joplinApiGenerator.noteApi.remove(id)
setList((list) => list.filter((item) => item.id !== id))
}
return (
<Card
title={i18n.t('checkParentNotebook.title')}
extra={
<Button loading={onCheckState.loading} onClick={onCheck}>
{i18n.t('common.action.check')}
</Button>
}
>
<List
dataSource={list}
locale={{ emptyText: i18n.t('checkParentNotebook.listEmptyText') }}
renderItem={(item) => (
<List.Item
id={item.id}
extra={
<Button onClick={() => onRemove(item.id)}>
{i18n.t('common.action.remove')}
</Button>
}
>
<Typography.Text>{item.title}</Typography.Text>
</List.Item>
)}
/>
</Card>
)
}
Example #4
Source File: LayoutView.tsx From joplin-utils with MIT License | 5 votes |
LayoutView: React.FC = () => {
const [language, setLanguage] = useLocalStorage<LanguageEnum>(
'language',
getLanguage(),
)
const [{ value: list }, fetch] = useAsyncFn(
async (language: LanguageEnum) => {
console.log('language: ', language)
await i18n.init({ en, zhCN }, language)
return routeList.map((item) => ({
...item,
title: i18n.t(item.title as any),
}))
},
[],
)
useMount(() => fetch(language!))
const [refreshKey, { inc }] = useCounter(0)
async function changeLanguage(value: LanguageEnum) {
setLanguage(value)
await fetch(value)
inc()
}
return (
<Layout className={css.app}>
<Layout.Sider className={css.sider} width="max-content">
<h2 className={css.logo}>Joplin Batch</h2>
<Menu>
{list &&
list.map((item) => (
<Menu.Item key={item.path as string}>
<Link to={item.path as string}>{item.title}</Link>
</Menu.Item>
))}
</Menu>
</Layout.Sider>
<Layout>
<Layout.Header className={css.header}>
<Select
options={[
{ label: 'English', value: LanguageEnum.En },
{ label: '中文', value: LanguageEnum.ZhCN },
]}
value={language}
onChange={changeLanguage}
/>
</Layout.Header>
<Layout.Content className={css.main}>
{list && <RouterView key={refreshKey} />}
</Layout.Content>
</Layout>
</Layout>
)
}
Example #5
Source File: NotFoundResourceCheckView.tsx From joplin-utils with MIT License | 5 votes |
NotFoundResourceCheckView: React.FC = () => {
const [list, setList] = useState<
(Pick<NoteProperties, 'id' | 'title' | 'user_updated_time'> & {
errorLinks: Pick<ResourceProperties, 'id' | 'title'>[]
})[]
>([])
const [loadingMsg, setLoadingMsg] = useState('')
const [state, onCheck] = useAsyncFn(async () => {
const list = await notFoundResourceCheckService
.check()
.on('load', (title) => setLoadingMsg(title))
.on('parse', (info) => {
setLoadingMsg(`[${info.rate}/${info.all}] ${info.title}`)
})
console.log('list: ', list)
setList(list)
})
return (
<Card
title={i18n.t('notFoundResource.title')}
extra={<Button onClick={onCheck}>{i18n.t('common.action.check')}</Button>}
>
<List
dataSource={list}
locale={{
emptyText: i18n.t('notFoundResource.listEmptyText'),
}}
renderItem={(note) => (
<List.Item
key={'note-' + note.id}
actions={[<Button onClick={() => openNote(note.id)}>{i18n.t('common.action.open')}</Button>]}
>
<List.Item.Meta
title={note.title}
description={
<List
className={css.subList}
dataSource={note.errorLinks}
renderItem={(item) => (
<List.Item key={'resource-' + note.id + '-' + item.id}>
<List.Item.Meta title={item.title || i18n.t('notFoundResource.unknownFileName', item)} />
</List.Item>
)}
/>
}
/>
</List.Item>
)}
loading={
{
spinning: state.loading,
tip: loadingMsg,
} as SpinProps
}
/>
</Card>
)
}
Example #6
Source File: UnusedResourceView.tsx From joplin-utils with MIT License | 5 votes |
UnusedResourceView: React.FC = () => {
const [list, setList] = useState<Pick<ResourceProperties, 'id' | 'title' | 'mime'>[]>([])
const [loadingMsg, setLoadingMsg] = useState('')
const [state, onCheck] = useAsyncFn(async () => {
try {
const list = await unusedResourceService.getUnusedResource().on('process', (info) => {
setLoadingMsg(i18n.t('unusedResource.msg.process', info))
})
console.log('list: ', list)
setList(list)
} catch (e) {
message.error(i18n.t('unusedResource.msg.error'))
}
})
async function onRemoveResource(id: string) {
setList(produce((list) => list.filter((item) => item.id !== id)))
await joplinApiGenerator.resourceApi.remove(id)
}
async function onOpenResource(id: string) {
await downloadUrl(buildResourceUrl(id))
}
const [onRemoveAllState, onRemoveAll] = useAsyncFn(async () => {
await AsyncArray.forEach(list, async (item) => {
await joplinApiGenerator.resourceApi.remove(item.id)
})
setList([])
}, [list])
return (
<Card
title={i18n.t('unusedResource.title')}
extra={
<Space>
<Button onClick={onCheck}>{i18n.t('common.action.check')}</Button>
<Button disabled={list.length === 0} danger={true} loading={onRemoveAllState.loading} onClick={onRemoveAll}>
{i18n.t('unusedResource.action.removeAll')}
</Button>
</Space>
}
>
<List
dataSource={list}
locale={{
emptyText: i18n.t('unusedResource.listEmptyText'),
}}
renderItem={(item) => (
<List.Item
key={item.id}
actions={[
<Button onClick={() => onRemoveResource(item.id)}>{i18n.t('common.action.remove')}</Button>,
<Button onClick={() => onOpenResource(item.id)}>{i18n.t('common.action.download')}</Button>,
]}
extra={item.mime.startsWith('image/') && <Image src={buildResourceUrl(item.id)} width={300} />}
>
<List.Item.Meta title={item.title} />
</List.Item>
)}
loading={
{
spinning: state.loading,
tip: loadingMsg,
} as SpinProps
}
/>
</Card>
)
}
Example #7
Source File: CheckoutReview.tsx From storefront with MIT License | 4 votes |
CheckoutReview: React.VFC<Props> = ({
cart,
creditCard,
customer,
loading,
onSubmit,
paymentMethod,
paymentNonce,
}) => {
const [customerNote, setCustomerNote] = useState<string>();
const [acceptTerms, setAcceptsTerms] = useState(false);
const [{ loading: paymentLoading }, handlePayment] = useAsyncFn(async (nonce?: string) => {
const response = await fetch('/api/payment', {
method: 'post',
credentials: 'include',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify({
nonce,
total: cart.total == null ? undefined : parseFloat(cart.total),
}),
});
const data = (await response.json()) as PaymentResponse;
onSubmit({
customerNote,
metaData: [
{
key: '_merchant_account_id',
value: process.env.BRAINTREE_MERCHANT_ID,
},
{
key: '_wc_braintree_environment',
value: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
},
{
key: '_transaction_status',
value: data.transaction.status,
},
],
transactionId: data.transaction.id,
});
});
const handleSubmit = () => {
handlePayment(paymentNonce);
};
if (loading || paymentLoading) {
return <Loader />;
}
return (
<>
<Grid container spacing={4}>
<Grid item xs={6}>
<Box
sx={{
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
mb: 1,
}}
>
<Typography variant="h4">Billing Address</Typography>
<IconButton href="/checkout/billing-address" size="small">
<Edit fontSize="inherit" />
</IconButton>
</Box>
<Divider />
<Box sx={{ mt: 2 }}>
<AddressSummary address={customer.billing} />
</Box>
</Grid>
<Grid item xs={6}>
<Box
sx={{
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
mb: 1,
}}
>
<Typography variant="h4">Shipping Address</Typography>
<IconButton href="/checkout/shipping-address" size="small">
<Edit fontSize="inherit" />
</IconButton>
</Box>
<Divider />
<Box sx={{ mt: 2 }}>
<AddressSummary address={customer.shipping} />
</Box>
</Grid>
<Grid item xs={6}>
<Box
sx={{
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
mb: 1,
}}
>
<Typography variant="h4">Shipping Method</Typography>
<IconButton href="/checkout/shipping-options" size="small">
<Edit fontSize="inherit" />
</IconButton>
</Box>
<Divider />
<Box sx={{ mt: 2 }}>
<ShippingSummary
availableShippingMethods={cart.availableShippingMethods}
chosenShippingMethods={cart.chosenShippingMethods}
/>
</Box>
</Grid>
<Grid item xs={6}>
<Box
sx={{
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
mb: 1,
}}
>
<Typography variant="h4">Payment Method</Typography>
<IconButton href="/checkout/payment" size="small">
<Edit fontSize="inherit" />
</IconButton>
</Box>
<Divider />
<Box sx={{ mt: 2 }}>
<PaymentSummary chosenPaymentMethod={paymentMethod} creditCard={creditCard} />
</Box>
</Grid>
</Grid>
<Box sx={{ mt: 6 }}>
<TextField
multiline
label="Note"
placeholder="Please sign my prints"
rows={3}
onChange={(ev) => setCustomerNote(ev.target.value)}
/>
<FormGroup>
<FormControlLabel
control={
<Checkbox
name="acceptTerms"
checked={acceptTerms}
onChange={(ev) => setAcceptsTerms(ev.target.checked)}
/>
}
label={
<>
With your order, you agree to have read and understood our{' '}
<Link href="/terms">Terms & Conditions</Link> your{' '}
<Link href="/revocation">Right of Recission</Link> and our{' '}
<Link href="/privacy-policy">Privacy Policy</Link>.
</>
}
/>
</FormGroup>
</Box>
<Box sx={{ mt: 6 }}>
{paymentMethod === 'braintree_paypal' ? (
<PaypalButton
cart={cart}
disabled={!acceptTerms}
shipping={customer.shipping}
paymentClientToken={process.env.BRAINTREE_TOKENIZATION_KEY}
onAuthorize={(nonce) => handlePayment(nonce)}
/>
) : (
<Button fullWidth color="primary" disabled={!acceptTerms} onClick={handleSubmit}>
Place your order
</Button>
)}
</Box>
</>
);
}
Example #8
Source File: ConvertExternalLinkView.tsx From joplin-utils with MIT License | 4 votes |
ConvertExternalLinkView: React.FC = () => {
const [list, setList] = useState<NoteModel[]>([])
const [onSearchState, onSearch] = useAsyncFn(async function onSearch(keyword: string) {
if (keyword === '') {
setList([])
return
}
const list = await convertExternalLinkService.search(keyword)
console.log('onSearch: ', list)
setList(list.filter(filterEmptyUrlsNote))
})
async function onConvertNote(data: {
noteId: string
linkNoteId: string
linkNoteTitle: string
url: string
noteIndex: number
urlIndex: number
}) {
console.log('onConvertNote: ', data)
await convertExternalLinkService.convert(data.noteId, {
[data.url]: {
title: JoplinMarkdownUtil.trimTitle(data.linkNoteTitle),
url: `:/${data.linkNoteId}`,
},
})
setList(
produce((list) => {
console.log('remove: ', data.noteIndex, data.urlIndex)
list[data.noteIndex].urls.splice(data.urlIndex, 1)
list.filter((note) => note.urls.length !== 0)
}),
)
setList((list) => list.filter(filterEmptyUrlsNote))
message.success(i18n.t('convertExternalLink.msg.success'))
}
return (
<Card title={i18n.t('convertExternalLink.title')}>
<Input.Search onSearch={onSearch} allowClear={true} loading={onSearchState.loading} />
<List
dataSource={list}
itemLayout={'vertical'}
loading={onSearchState.loading}
renderItem={(note, noteIndex) => (
<List.Item
key={note.id}
extra={[<Button onClick={() => openNote(note.id)}>{i18n.t('common.action.open')}</Button>]}
>
<Typography.Title level={4}>{note.title}</Typography.Title>
<List
dataSource={note.urls}
className={css.sub1}
itemLayout={'vertical'}
renderItem={(url, urlIndex) => (
<List.Item key={urlIndex}>
<Typography.Title level={5}>{url.title}</Typography.Title>
<Typography.Link>{url.url}</Typography.Link>
{url.matchNotes && url.matchNotes.length !== 0 && (
<MatchNoteList
url={url}
onConvertNote={(matchNote) =>
onConvertNote({
noteId: note.id,
url: url.url,
linkNoteId: matchNote.id,
linkNoteTitle: matchNote.title,
noteIndex,
urlIndex,
})
}
/>
)}
</List.Item>
)}
/>
</List.Item>
)}
/>
</Card>
)
}
Example #9
Source File: FixFileExtensionView.tsx From joplin-utils with MIT License | 4 votes |
FixFileExtensionView: React.FC = () => {
const [list, setList] = useState<
Pick<ResourceProperties, 'id' | 'title' | 'file_extension' | 'mime'>[]
>([])
const [loadState, fetch] = useAsyncFn(async () => {
setList(
(
await PageUtil.pageToAllList(
joplinApiGenerator.resourceApi.list.bind(
joplinApiGenerator.resourceApi,
),
{
fields: ['id', 'title', 'file_extension', 'mime'],
},
)
)
.filter((item) => !item.file_extension)
.map((item) => ({
...item,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
file_extension: MimeUtils.toFileExtension(item.mime)!,
})),
)
})
async function onFix() {
const hide = message.loading(i18n.t('fixFileExtension.action.progress'))
try {
await AsyncArray.forEach(
list,
asyncLimiting(async (item) => {
await joplinApiGenerator.resourceApi.update({
id: item.id,
file_extension: item.file_extension,
})
}, 10),
)
setList([])
message.success(i18n.t('fixFileExtension.action.complete'))
} finally {
hide()
}
}
return (
<Card
title={i18n.t('fixFileExtension.title')}
extra={
<Space>
<Button onClick={fetch}>{i18n.t('common.action.check')}</Button>
<Button disabled={list.length === 0} onClick={onFix}>
{i18n.t('fixFileExtension.action.fix')}
</Button>
</Space>
}
>
<List
dataSource={list ?? []}
renderItem={(item) => (
<List.Item
key={item.id}
extra={
item.mime.startsWith('image/') && (
<Image src={buildResourceUrl(item.id)} width={300} />
)
}
>
<List.Item.Meta
title={item.title}
description={`${i18n.t('fixFileExtension.tip')}${
item.file_extension
}`}
/>
</List.Item>
)}
loading={
{
spinning: loadState.loading,
} as SpinProps
}
/>
</Card>
)
}