react-query#useQueries JavaScript Examples
The following examples show how to use
react-query#useQueries.
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: hooks.js From idena-web with MIT License | 5 votes |
export function useProfileAds() {
const rpcFetcher = useRpcFetcher()
const [{profileHash}, {forceUpdate: forceIdentityUpdate}] = useIdentity()
const {decodeProfile, decodeAd, decodeAdTarget} = useProtoProfileDecoder()
const {data: profile, status: profileStatus} = useQuery({
queryKey: ['ipfs_get', [profileHash]],
queryFn: rpcFetcher,
enabled: Boolean(profileHash),
select: decodeProfile,
staleTime: Infinity,
notifyOnChangeProps: 'tracked',
})
const queryClient = useQueryClient()
const decodedProfileAds = useQueries(
profile?.ads?.map(({cid, target, ...ad}) => ({
queryKey: ['decodedProfileAd', [cid]],
queryFn: async () => ({
...decodeAd(
await queryClient
.fetchQuery({
queryKey: ['ipfs_get', [cid]],
queryFn: rpcFetcher,
staleTime: Infinity,
})
.catch(() => '')
),
...decodeAdTarget(target),
cid,
...ad,
}),
enabled: Boolean(cid),
staleTime: Infinity,
})) ?? []
)
const profileAds = useQueries(
decodedProfileAds
.filter(({data}) => Boolean(data?.contract))
.map(({data}) => {
const {cid, contract, ...ad} = data
return {
queryKey: ['profileAd', cid, contract],
queryFn: async () => ({
...ad,
cid,
status: AdStatus.Published,
}),
}
})
)
const status =
profileStatus === 'loading' ||
(profileHash === undefined
? true
: Boolean(profileHash) && profileStatus === 'idle') ||
decodedProfileAds.some(ad => ad.status === 'loading') ||
profileAds.some(ad => ad.status === 'loading')
? 'loading'
: 'done'
return {
data: profileAds.map(({data}) => data) ?? [],
status,
refetch: forceIdentityUpdate,
}
}
Example #2
Source File: hooks.js From idena-web with MIT License | 4 votes |
export function useRotatingAds(limit = 3) {
const rpcFetcher = useRpcFetcher()
const burntCoins = useTargetedAds()
const addresses = [...new Set(burntCoins?.map(({address}) => address))]
const profileHashes = useQueries(
addresses.map(address => ({
queryKey: ['dna_identity', [address]],
queryFn: rpcFetcher,
staleTime: 5 * 60 * 1000,
notifyOnChangeProps: ['data', 'error'],
select: selectProfileHash,
}))
)
const {decodeAd, decodeProfile} = useProtoProfileDecoder()
const profiles = useQueries(
profileHashes.map(({data: cid}) => ({
queryKey: ['ipfs_get', [cid]],
queryFn: rpcFetcher,
enabled: Boolean(cid),
select: decodeProfile,
staleTime: Infinity,
notifyOnChangeProps: ['data'],
}))
)
const profileAdVotings = useQueries(
profiles
.map(({data}) => data?.ads)
.flat()
.map(ad => ({
queryKey: ['profileAdVoting', ad?.contract],
queryFn: () => getAdVoting(ad?.contract),
enabled: Boolean(ad?.contract),
staleTime: 5 * 60 * 1000,
select: data => ({...data, cid: ad?.cid}),
}))
)
const approvedProfileAdVotings = profileAdVotings?.filter(({data}) =>
isApprovedVoting(data)
)
const queryClient = useQueryClient()
const decodedProfileAds = useQueries(
burntCoins
?.filter(({key}) =>
approvedProfileAdVotings.some(
({data}) => data?.cid === AdBurnKey.fromHex(key).cid
)
)
.slice(0, limit)
.map(({key, address, amount}) => {
const {cid} = AdBurnKey.fromHex(key)
return {
queryKey: ['decodedRotatingAd', [cid]],
queryFn: async () => ({
...decodeAd(
await queryClient
.fetchQuery({
queryKey: ['ipfs_get', [cid]],
queryFn: rpcFetcher,
staleTime: Infinity,
})
.catch(() => '')
),
cid,
author: address,
amount: Number(amount),
}),
enabled: Boolean(cid),
staleTime: Infinity,
}
}) ?? []
)
return decodedProfileAds?.map(x => x.data).filter(Boolean) ?? []
}
Example #3
Source File: demo.story.js From react-table-library with MIT License | 4 votes |
Demo = () => {
// dropdown
const [isDropdownOpen, setDropdownOpen] = React.useState(null);
const handleDropdownOpen = (event, id) => setDropdownOpen({ element: event.currentTarget, id });
const handleDropdownClose = () => setDropdownOpen(null);
// expand
const [expandedMarketIds, setExpandedMarketIds] = React.useState([]);
const handleExpand = (incomingId) => {
const id = incomingId || isDropdownOpen?.id || '';
if (expandedMarketIds.includes(id)) {
setExpandedMarketIds(expandedMarketIds.filter((value) => value !== id));
} else {
setExpandedMarketIds(expandedMarketIds.concat(id));
}
};
// percentages
const [percentageUnitOne, setPercentageUnitOne] = React.useState(
'price_change_percentage_24h_in_currency',
);
const [percentageUnitTwo, setPercentageUnitTwo] = React.useState(
'price_change_percentage_7d_in_currency',
);
// watchlist
const [watched, setWatched] = useLocalStorageState('watched', {
defaultValue: [],
});
// category
const [activeCategory, setActiveCategory] = React.useState(DEFAULT_CATEGORY);
// customize
const [isCustomizeActive, setCustomizeActive] = React.useState(false);
const [hiddenColumns, setHiddenColumns] = React.useState(Object.keys(CUSTOM_COLUMNS));
// theming
const theme = useTheme([CUSTOM_SHARED_THEME, CUSTOM_PRIMARY_THEME]);
// data
const [currencies, setCurrencies] = React.useState([]);
const [fetchState, setFetchState] = React.useState({
isLoading: false,
isOverlayLoading: false,
error: null,
});
const fetchCurrencies = async ({ page, size, category }, fetchState) => {
setFetchState(fetchState);
setCurrencies(
await queryClient.fetchQuery(['currencies'], queryCurrencies({ page, size, category })),
);
setFetchState({ isLoading: false, isOverlayLoading: false, error: null });
};
const marketsData = useQueries(
expandedMarketIds.map((id) => ({
queryKey: ['market', id],
queryFn: queryMarkets(id),
})),
);
const data = {
nodes: activeCategory === WATCHLIST_CATEGORY ? watched : currencies,
};
// pagination
const pagination = usePagination(
data,
{
state: {
page: DEFAULT_PAGE,
size: DEFAULT_SIZE,
},
onChange: onPaginationChange,
},
{
isServer: activeCategory === WATCHLIST_CATEGORY ? false : true,
},
);
function onPaginationChange(action, state) {
fetchCurrencies(
{ page: state.page + 1, size: state.size, category: activeCategory },
{ isOverlayLoading: true },
);
}
// activeCategory
useCustom('activeCategory', data, {
state: { activeCategory },
onChange: onActiveCategoryChange,
});
function onActiveCategoryChange(action, state) {
const size = state.activeCategory === DEFAULT_CATEGORY ? 10 : 50; // TODO
pagination.fns.onSetPage(DEFAULT_PAGE);
pagination.fns.onSetSize(size);
fetchCurrencies(
{
page: DEFAULT_PAGE,
size: size,
category: state.activeCategory,
},
{ isOverlayLoading: true },
);
}
// watchlist handler
const handleFavorite = (item) => {
if (watched.map((value) => value.id).includes(item.id)) {
setWatched(watched.filter((value) => value.id !== item.id));
} else {
setWatched(watched.concat(item));
}
};
const handleWatchList = () => {
pagination.fns.onSetPage(DEFAULT_PAGE);
pagination.fns.onSetSize(DEFAULT_SIZE);
setActiveCategory(WATCHLIST_CATEGORY);
};
// reactive query
React.useEffect(() => {
fetchCurrencies(
{
page: DEFAULT_PAGE,
size: DEFAULT_SIZE,
category: activeCategory,
},
{ isLoading: true },
);
}, [activeCategory]);
return (
<>
<Stack
direction="row"
justifyContent="space-between"
style={{
borderBottom: '1px solid #D4D4D4',
overflowX: 'auto',
}}
>
<Stack direction="row" spacing={1} m={1}>
<Button
color="secondary"
size="small"
variant={activeCategory === WATCHLIST_CATEGORY ? 'outlined' : 'text'}
startIcon={activeCategory === WATCHLIST_CATEGORY ? <StarIcon /> : <StarOutlineIcon />}
onClick={handleWatchList}
>
Watchlist
</Button>
<Button color="secondary" size="small" startIcon={<PieChartIcon />} onClick={() => {}}>
Portfolio
</Button>
<Divider orientation="vertical" flexItem />
{Object.keys(CATEGORIES).map((key) => (
<Button
key={key}
color="secondary"
size="small"
variant={key === activeCategory ? 'outlined' : 'text'}
onClick={() => setActiveCategory(key)}
>
{CATEGORIES[key].label}
</Button>
))}
</Stack>
<Stack direction="row" spacing={1} m={1}>
<Button
color="secondary"
size="small"
variant={isCustomizeActive ? 'outlined' : 'text'}
onClick={() => setCustomizeActive(!isCustomizeActive)}
>
Customize
</Button>
</Stack>
</Stack>
{isCustomizeActive && (
<Stack
direction="row"
justifyContent="space-between"
style={{
borderBottom: '1px solid #D4D4D4',
overflowX: 'auto',
}}
>
<Stack direction="row" alignItems="center" spacing={1} m={1}>
<small style={{ textTransform: 'uppercase' }}>Add Columns:</small>
{Object.keys(CUSTOM_COLUMNS).map((key) => (
<Button
key={key}
color="secondary"
size="small"
variant={hiddenColumns.includes(key) ? 'text' : 'outlined'}
onClick={() =>
hiddenColumns.includes(key)
? setHiddenColumns(hiddenColumns.filter((value) => value !== key))
: setHiddenColumns(hiddenColumns.concat(key))
}
>
{CUSTOM_COLUMNS[key].label}
</Button>
))}
</Stack>
<Stack direction="row" spacing={1} m={1}>
{hiddenColumns.length < Object.keys(CUSTOM_COLUMNS).length && (
<Button
color="secondary"
size="small"
onClick={() => setHiddenColumns(Object.keys(CUSTOM_COLUMNS))}
>
Clear Columns
</Button>
)}
</Stack>
</Stack>
)}
<div style={{ position: 'relative' }}>
<Table
data={data}
theme={theme}
layout={{ custom: true, horizontalScroll: true }}
pagination={pagination}
>
{(tableList) => (
<>
<Header>
<HeaderRow>
<HeaderCell resize pinLeft />
<HeaderCell resize pinLeft>
#
</HeaderCell>
<HeaderCell resize pinLeft>
Name
</HeaderCell>
<HeaderCell resize>Price</HeaderCell>
<HeaderCell resize>
<StyledSelect
value={percentageUnitOne}
onChange={(event) => setPercentageUnitOne(event.target.value)}
>
{Object.keys(PRICE_CHANGE_PERCENTAGE).map((key) => (
<MenuItem key={key} value={key}>
{PRICE_CHANGE_PERCENTAGE[key].label}
</MenuItem>
))}
</StyledSelect>
</HeaderCell>
<HeaderCell resize>
<StyledSelect
value={percentageUnitTwo}
onChange={(event) => setPercentageUnitTwo(event.target.value)}
>
{Object.keys(PRICE_CHANGE_PERCENTAGE).map((key) => (
<MenuItem key={key} value={key}>
{PRICE_CHANGE_PERCENTAGE[key].label}
</MenuItem>
))}
</StyledSelect>
</HeaderCell>
<HeaderCell resize>Market Cap</HeaderCell>
<HeaderCell resize>Circulating Supply</HeaderCell>
<HeaderCell resize={hiddenColumns.length !== Object.keys(CUSTOM_COLUMNS).length}>
Last 7 Days
</HeaderCell>
{Object.keys(CUSTOM_COLUMNS).map((column) => (
<HeaderCell
key={column}
resize
hide={hiddenColumns.includes(column)}
className="small"
>
<AlignCenter>
{CUSTOM_COLUMNS[column].label}
<IconButton
size="small"
onClick={() => setHiddenColumns(hiddenColumns.concat(column))}
>
<CloseIcon />
</IconButton>
</AlignCenter>
</HeaderCell>
))}
<HeaderCell pinRight />
</HeaderRow>
</Header>
<Body>
{tableList.map((item) => {
const marketData = marketsData?.find(
(market) => market?.data?.name.toLowerCase() === item.id.toLowerCase(),
);
return (
<React.Fragment key={item.id}>
<Row item={item}>
<Cell pinLeft>
<Tooltip title="Add to Main Watchlist" arrow>
<IconButton size="small" onClick={() => handleFavorite(item)}>
{watched.map((value) => value.id).includes(item.id) ? (
<StarIcon fontSize="small" />
) : (
<StarOutlineIcon fontSize="small" />
)}
</IconButton>
</Tooltip>
</Cell>
<Cell pinLeft>{item.market_cap_rank}</Cell>
<Cell pinLeft>
<AlignCenter>
<img alt="icon" src={item.image} width={20} height={20} />
<Ellipse>
{item.name}
<span style={{ color: '#808a9d' }}>{item.symbol.toUpperCase()}</span>
</Ellipse>
</AlignCenter>
</Cell>
<Cell>
{item.current_price.toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
})}
</Cell>
<Cell>
<Indicator value={twoDecimals(item[percentageUnitOne])} suffix="%" />
</Cell>
<Cell>
<Indicator value={twoDecimals(item[percentageUnitTwo])} suffix="%" />
</Cell>
<Cell>
{item.market_cap.toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
})}
</Cell>
<Cell>
{item.circulating_supply} {item.symbol.toUpperCase()}
{item.max_supply && (
<LinearProgress
variant="determinate"
value={twoDecimals((item.circulating_supply / item.max_supply) * 100)}
/>
)}
</Cell>
<Cell>
<Sparklines data={item.sparkline_in_7d.price} height={40}>
<SparklinesLine color="#439867" />
</Sparklines>
</Cell>
{Object.keys(CUSTOM_COLUMNS).map((column) => (
<Cell
key={column}
hide={hiddenColumns.includes(column)}
className="small"
>
{CUSTOM_COLUMNS[column].render(item)}
</Cell>
))}
<Cell pinRight>
<ViewMarket
marketData={marketData}
item={item}
isExpanded={expandedMarketIds.includes(item.id)}
onOpen={handleDropdownOpen}
onClose={handleExpand}
/>
</Cell>
</Row>
{marketData?.isFetched && expandedMarketIds.includes(item.id) && (
<MarketsTable
data={{
nodes: marketData?.data.tickers || [],
}}
hiddenColumns={hiddenColumns}
/>
)}
</React.Fragment>
);
})}
</Body>
</>
)}
</Table>
</div>
{fetchState.isLoading && <Loading />}
{fetchState.isOverlayLoading && <OverlayLoading />}
<TablePagination
count={
activeCategory === WATCHLIST_CATEGORY ? data.nodes.length : 9688 // TODO API does not offer this number
}
page={pagination.state.page}
rowsPerPage={pagination.state.size}
rowsPerPageOptions={activeCategory === DEFAULT_CATEGORY ? [10, 25, 50, 100] : [50]} // TODO
onRowsPerPageChange={(event) => pagination.fns.onSetSize(parseInt(event.target.value, 10))}
onPageChange={(event, page) => pagination.fns.onSetPage(page)}
/>
<Menu
anchorEl={isDropdownOpen?.element}
open={!!isDropdownOpen}
onClose={handleDropdownClose}
onClick={handleDropdownClose}
>
<MenuItem onClick={() => handleExpand()}>View Markets</MenuItem>
</Menu>
</>
);
}