react-redux#useStore TypeScript Examples
The following examples show how to use
react-redux#useStore.
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: index.tsx From datart with Apache License 2.0 | 6 votes |
useInjectReducer = ({ key, reducer }: InjectReducerParams) => {
const store = useStore();
const isInjected = React.useRef(false);
if (!isInjected.current) {
getInjectors(store).injectReducer(key, reducer);
isInjected.current = true;
}
}
Example #2
Source File: DragndropPostList.tsx From clearflask with Apache License 2.0 | 5 votes |
DragndropPostListPostListInner = React.memo((props: {
PostListProps: React.ComponentProps<typeof PostList>;
dragSelectedTourAnchorProps?: React.ComponentProps<typeof TourAnchor>;
}) => {
const theme = useTheme();
const store = useStore();
return (
<PostList
{...props.PostListProps}
PanelPostProps={{
margins: theme.spacing(DashboardListPostSpacing, DashboardListPostSpacing, DashboardListPostSpacing, DashboardListPostSpacing + 1),
...props.PostListProps.PanelPostProps,
wrapPost: (post, content, index) => (
<Draggable
draggableId={post.ideaId}
index={index}
>
{(providedDraggable, snapshotDraggable) => {
var inner = content;
if (props.dragSelectedTourAnchorProps) {
if (!!props.PostListProps.selected && lastSelectedId !== props.PostListProps.selected) {
lastSelectedId = props.PostListProps.selected;
}
if (lastSelectedId === post.ideaId) {
inner = (
<Provider store={ServerAdmin.get().getStore()}>
<TourAnchor placement='top' {...props.dragSelectedTourAnchorProps} zIndex={zb => zb.modal - 1}>
<Provider store={store}>
{inner}
</Provider>
</TourAnchor>
</Provider>
);
}
}
inner = (
<DragndropPostListDraggableInner
providedDraggable={providedDraggable}
isDragging={snapshotDraggable.isDragging}
draggingOver={snapshotDraggable.draggingOver}
dropAnimation={snapshotDraggable.dropAnimation}
content={inner}
/>
);
return inner as any;
}}
</Draggable>
),
}}
/>
);
}, customReactMemoEquals({ nested: new Set(['dragSelectedTourAnchorProps', 'PostListProps']) }))
Example #3
Source File: useConnector.ts From reactant with MIT License | 5 votes |
/**
* ## Description
*
* `useConnector` is a React Hooks, which you can use to inject any shared state and derived data that you want to render using.
* And it supports both `useConnector(() => this.renderPropsValue)` and `useConnector(() => this.getMapStateToProps())` uses.
*
* ## Example
*
* ```tsx
* @injectable()
* class FooView extends ViewModule {
* @state
* key = 'str';
*
* @action
* setValue(value: any) {
* this.key = value;
* }
*
* component() {
* const { key } = useConnector(() => ({ key: this.key }));
* // or `const key = useConnector(() => this.key);`
* return <span>{key}</span>;
* }
* }
*
* const container = document.createElement('div');
* document.body.appendChild(container);
*
* act(() => {
* createApp({
* modules: [],
* main: FooView,
* render,
* }).bootstrap(container);
* });
*
* expect(container.querySelector('span')?.textContent).toBe('str');
* ```
*/
export function useConnector<T>(
selector: () => T,
shallowEqual?: ShallowEqual
) {
try {
return useSelector(
selector,
shallowEqual || areShallowEqualWithObject
) as T;
} catch (e) {
try {
useStore();
} catch (error) {
console.error(`No class with a field decorated by '@state' is injected.`);
throw e;
}
throw e;
}
}
Example #4
Source File: IdeApp.tsx From kliveide with MIT License | 4 votes |
IdeApp: React.VFC = () => {
// --- Let's use the store for dispatching actions
const store = useStore();
const dispatch = useDispatch();
// --- Component state (changes of them triggers re-rendering)
const [themeStyle, setThemeStyle] = useState<CSSProperties>({});
const [themeClass, setThemeClass] = useState("");
const ideLoaded = useSelector((s: AppState) => s.ideUiLoaded);
const showStatusBar = useSelector(
(s: AppState) => s.emuViewOptions.showStatusBar
);
const showSidebar = useSelector(
(s: AppState) => s.emuViewOptions.showSidebar
);
const showToolFrame = useSelector((s: AppState) => s.toolFrame.visible);
const showDocuments = useSelector(
(s: AppState) => !s.toolFrame.visible || !s.toolFrame.maximized
);
const mounted = useRef(false);
useEffect(() => {
const themeService = getThemeService();
// --- State change event handlers
const isWindowsChanged = (isWindows: boolean) => {
themeService.isWindows = isWindows;
updateThemeState();
};
const themeChanged = (theme: string) => {
themeService.setTheme(theme);
updateThemeState();
};
if (!mounted.current) {
// --- Mount logic, executed only once during the app's life cycle
mounted.current = true;
updateThemeState();
getStore().themeChanged.on(themeChanged);
getStore().isWindowsChanged.on(isWindowsChanged);
// --- Set up activities
}
return () => {
// --- Unsubscribe
getStore().isWindowsChanged.off(isWindowsChanged);
getStore().themeChanged.off(themeChanged);
mounted.current = false;
};
}, [store]);
// --- Apply styles to body so that dialogs, context menus can use it, too.
document.body.setAttribute("style", toStyleString(themeStyle));
document.body.setAttribute("class", themeClass);
return (
<>
{ideLoaded && (
<Fill id="klive_ide_app">
<Row>
<Column width={48}>
<ActivityBar />
</Column>
<SplitPanel
splitterSize={4}
horizontal={true}
panel1MinSize={MIN_SIDEBAR_WIDTH}
panel2MinSize={MIN_DESK_WIDTH}
initialSize={"20%"}
panel1={<SideBar />}
showPanel1={showSidebar}
panel2={
<SplitPanel
splitterSize={4}
horizontal={false}
reverse={true}
panel1MinSize={MIN_TOOL_HEIGHT}
showPanel1={showToolFrame}
panel1={<ToolFrame />}
panel2MinSize={MIN_DESK_HEIGHT}
showPanel2={showDocuments}
panel2={<IdeDocumentFrame />}
initialSize="33%"
/>
}
/>
</Row>
<Row
height="fittoclient"
style={{ display: showStatusBar ? undefined : "none" }}
>
<IdeStatusbar />
</Row>
<IdeContextMenu target="#klive_ide_app" />
<ModalDialog targetId="#app" />
</Fill>
)}
</>
);
/**
* Updates the current theme to dislay the app
* @returns
*/
function updateThemeState(): void {
const themeService = getThemeService();
const theme = themeService.getActiveTheme();
if (!theme) {
return;
}
setThemeStyle(themeService.getThemeStyle());
setThemeClass(`app-container ${theme.name}-theme`);
}
}
Example #5
Source File: App.tsx From polkabtc-ui with Apache License 2.0 | 4 votes |
function App(): JSX.Element {
const polkaBtcLoaded = useSelector((state: StoreType) => state.general.polkaBtcLoaded);
const address = useSelector((state: StoreType) => state.general.address);
const [isLoading, setIsLoading] = React.useState(true);
const dispatch = useDispatch();
const store = useStore();
// Load the main PolkaBTC API - connection to the PolkaBTC bridge
const loadPolkaBTC = React.useCallback(async (): Promise<void> => {
try {
window.polkaBTC = await connectToParachain();
dispatch(isPolkaBtcLoaded(true));
setIsLoading(false);
} catch (error) {
toast.warn('Unable to connect to the BTC-Parachain.');
console.log('Unable to connect to the BTC-Parachain.');
console.log('error.message => ', error.message);
}
try {
startFetchingLiveData(dispatch, store);
} catch (error) {
console.log('Error fetching live data.');
console.log('error.message => ', error.message);
}
}, [
dispatch,
store
]);
// Load the connection to the faucet - only for testnet purposes
const loadFaucet = React.useCallback(async (): Promise<void> => {
try {
window.faucet = new FaucetClient(constants.FAUCET_URL);
dispatch(isFaucetLoaded(true));
} catch (error) {
console.log('Unable to connect to the faucet.');
console.log('error.message => ', error.message);
}
}, [
dispatch
]);
React.useEffect(() => {
if (!polkaBtcLoaded) return;
if (!address) return;
const id = window.polkaBTC.api.createType(ACCOUNT_ID_TYPE_NAME, address);
// Maybe load the vault client - only if the current address is also registered as a vault
(async () => {
try {
dispatch(isVaultClientLoaded(false));
const vault = await window.polkaBTC.vaults.get(id);
dispatch(isVaultClientLoaded(!!vault));
} catch (error) {
// TODO: should add error handling
console.log('No PolkaBTC vault found for the account in the connected Polkadot wallet.');
console.log('error.message => ', error.message);
}
})();
// Maybe load the staked relayer client - only if the current address is also registered as a vault
(async () => {
try {
dispatch(isStakedRelayerLoaded(false));
const stakedRelayers = await window.polkaBTC.stakedRelayer.list();
dispatch(isStakedRelayerLoaded(stakedRelayers.includes(id)));
} catch (error) {
// TODO: should add error handling
console.log('No PolkaBTC staked relayer found for the account in the connected Polkadot wallet.');
console.log('error.message => ', error.message);
}
})();
}, [
polkaBtcLoaded,
address,
dispatch
]);
React.useEffect(() => {
// Do not load data if showing static landing page only
if (checkStaticPage()) return;
if (!polkaBtcLoaded) return;
// Initialize data on app bootstrap
(async () => {
try {
const [
totalPolkaBTC,
totalLockedDOT,
btcRelayHeight,
bitcoinHeight,
state
] = await Promise.all([
window.polkaBTC.treasury.total(),
window.polkaBTC.collateral.totalLocked(),
window.polkaBTC.btcRelay.getLatestBlockHeight(),
window.polkaBTC.electrsAPI.getLatestBlockHeight(),
window.polkaBTC.stakedRelayer.getCurrentStateOfBTCParachain()
]);
const parachainStatus = (state: StatusCode) => {
if (state.isError) {
return ParachainStatus.Error;
} else if (state.isRunning) {
return ParachainStatus.Running;
} else if (state.isShutdown) {
return ParachainStatus.Shutdown;
} else {
return ParachainStatus.Loading;
}
};
dispatch(
initGeneralDataAction(
displayBtcAmount(totalPolkaBTC),
displayDotAmount(totalLockedDOT),
Number(btcRelayHeight),
bitcoinHeight,
parachainStatus(state)
)
);
} catch (error) {
// TODO: should have error handling instead of console
console.log(error);
}
})();
}, [
dispatch,
polkaBtcLoaded
]);
// Loads the address for the currently select account and maybe loads the vault and staked relayer dashboards
React.useEffect(() => {
if (checkStaticPage()) return; // Do not load data if showing static landing page only
if (!polkaBtcLoaded) return;
(async () => {
const theExtensions = await web3Enable(APP_NAME);
if (theExtensions.length === 0) return;
dispatch(setInstalledExtensionAction(theExtensions.map(extension => extension.name)));
const accounts = await web3Accounts();
if (accounts.length === 0) {
dispatch(changeAddressAction(''));
return;
}
const matchedAccount = accounts.find(account => account.address === address);
const newAddress = matchedAccount ? address : accounts[0].address;
const { signer } = await web3FromAddress(newAddress);
// TODO: could store the active address just in one place (either in `window` object or in redux)
window.polkaBTC.setAccount(newAddress, signer);
dispatch(changeAddressAction(newAddress));
})();
}, [
address,
polkaBtcLoaded,
dispatch
]);
// Loads the PolkaBTC bridge and the faucet
React.useEffect(() => {
// Do not load data if showing static landing page only
if (checkStaticPage()) return;
if (polkaBtcLoaded) return;
(async () => {
try {
// TODO: should avoid any race condition
setTimeout(() => {
if (isLoading) setIsLoading(false);
}, 3000);
await loadPolkaBTC();
await loadFaucet();
keyring.loadAll({});
} catch (error) {
console.log(error.message);
}
})();
startFetchingLiveData(dispatch, store);
}, [
loadPolkaBTC,
loadFaucet,
isLoading,
polkaBtcLoaded,
dispatch,
store
]);
return (
<>
<ToastContainer
position='top-right'
autoClose={5000}
hideProgressBar={false} />
<Layout>
<LazyLoadingErrorBoundary>
<Route
render={({ location }) => {
if (checkStaticPage()) {
const pageURLs = [
PAGES.stakedRelayer,
PAGES.vaults,
PAGES.challenges,
PAGES.parachain,
PAGES.oracles,
PAGES.issue,
PAGES.redeem,
PAGES.relay,
PAGES.dashboard,
PAGES.vault,
PAGES.feedback,
PAGES.application
];
for (const pageURL of pageURLs) {
if (matchPath(location.pathname, { path: pageURL })) {
return <Redirect to={PAGES.home} />;
}
}
}
return (
// TODO: block for now
// <TransitionWrapper location={location}>
// TODO: should use loading spinner instead of `Loading...`
<React.Suspense fallback={<div>Loading...</div>}>
<Switch location={location}>
<Route path={PAGES.stakedRelayer}>
<StakedRelayer />
</Route>
<Route path={PAGES.vaults}>
<VaultsDashboard />
</Route>
<Route path={PAGES.challenges}>
<Challenges />
</Route>
<Route path={PAGES.parachain}>
<ParachainDashboard />
</Route>
<Route path={PAGES.oracles}>
<OraclesDashboard />
</Route>
<Route path={PAGES.issue}>
<IssueRequests />
</Route>
<Route path={PAGES.redeem}>
<RedeemRequests />
</Route>
<Route path={PAGES.relay}>
<RelayDashboard />
</Route>
<Route path={PAGES.dashboard}>
<Dashboard />
</Route>
<Route path={PAGES.vault}>
<VaultDashboard />
</Route>
<Route path={PAGES.feedback}>
<Feedback />
</Route>
<Route
exact
path={PAGES.application}>
<Application />
</Route>
<Route
path={PAGES.home}
exact>
<LandingPage />
</Route>
<Route path='*'>
<NoMatch />
</Route>
</Switch>
</React.Suspense>
// </TransitionWrapper>
);
}} />
</LazyLoadingErrorBoundary>
</Layout>
</>
);
}
Example #6
Source File: reimburse-view.tsx From polkabtc-ui with Apache License 2.0 | 4 votes |
export default function ReimburseView(props: ReimburseViewProps): ReactElement {
const [isReimbursePending, setReimbursePending] = useState(false);
const [isRetryPending, setRetryPending] = useState(false);
const { polkaBtcLoaded, prices } = useSelector((state: StoreType) => state.general);
const [punishmentDOT, setPunishmentDOT] = useState(new Big(0));
const [amountDOT, setAmountDOT] = useState(new Big(0));
const dispatch = useDispatch();
const store = useStore();
const { t } = useTranslation();
useEffect(() => {
const fetchData = async () => {
if (!polkaBtcLoaded) return;
try {
const [punishment, btcDotRate] = await Promise.all([
window.polkaBTC.vaults.getPunishmentFee(),
window.polkaBTC.oracle.getExchangeRate()
]);
const amountPolkaBTC = props.request ? new Big(props.request.amountPolkaBTC) : new Big(0);
setAmountDOT(amountPolkaBTC.mul(btcDotRate));
setPunishmentDOT(amountPolkaBTC.mul(btcDotRate).mul(new Big(punishment)));
} catch (error) {
console.log(error);
}
};
fetchData();
}, [props.request, polkaBtcLoaded]);
const onRetry = async () => {
if (!polkaBtcLoaded) return;
setRetryPending(true);
try {
if (!props.request) return;
const redeemId = window.polkaBTC.api.createType('H256', '0x' + props.request.id);
await window.polkaBTC.redeem.cancel(redeemId, false);
dispatch(retryRedeemRequestAction(props.request.id));
await fetchBalances(dispatch, store);
props.onClose();
toast.success(t('redeem_page.successfully_cancelled_redeem'));
} catch (error) {
console.log(error);
}
setRetryPending(false);
};
const onBurn = async () => {
if (!polkaBtcLoaded) return;
setReimbursePending(true);
try {
if (!props.request) return;
const redeemId = window.polkaBTC.api.createType('H256', '0x' + props.request.id);
await window.polkaBTC.redeem.cancel(redeemId, true);
dispatch(reimburseRedeemRequestAction(props.request.id));
await fetchBalances(dispatch, store);
props.onClose();
} catch (error) {
console.log(error);
}
setReimbursePending(false);
};
return (
<React.Fragment>
<div className='row mt-3'>
<div className='col reimburse-title'>
<p className='mb-4'>
<i className='fas fa-exclamation-circle'></i>
{t('redeem_page.sorry_redeem_failed')}
</p>
</div>
</div>
<div className='row justify-center mt-4'>
<div className='col-9 reimburse-send'>
{t('redeem_page.vault_did_not_send')}
<span>{punishmentDOT.toFixed(2).toString()} DOT </span> (~${' '}
{getUsdAmount(punishmentDOT.toString(), prices.polkadot.usd)})
{t('redeem_page.compensation')}
</div>
</div>
<div className='row justify-center'>
<div className='col-9 to-redeem'>
<p className='mb-4'>{t('redeem_page.to_redeem_polkabtc')}</p>
</div>
</div>
<div className='row justify-center'>
<div className='col-9 receive-compensation'>
{t('redeem_page.receive_compensation')}
<span>{punishmentDOT.toFixed(2)} DOT</span>
{t('redeem_page.retry_with_another', {
compensationPrice: getUsdAmount(punishmentDOT.toString(), prices.polkadot.usd)
})}
</div>
</div>
<div className='row justify-center'>
<div className='col-6 retry'>
<ButtonMaybePending
className='btn green-button app-btn'
disabled={isRetryPending || isReimbursePending}
isPending={isRetryPending}
onClick={onRetry}>
{t('retry')}
</ButtonMaybePending>
</div>
</div>
<div className='row justify-center mt-4'>
<div className='col-10 burn-desc'>
{t('redeem_page.burn_polkabtc')}
<span>{amountDOT.toFixed(5).toString()} DOT</span>
{t('redeem_page.with_added', {
amountPrice: getUsdAmount(amountDOT.toString(), prices.polkadot.usd)
})}
<span>{punishmentDOT.toFixed(5).toString()} DOT</span>
{t('redeem_page.as_compensation_instead', {
compensationPrice: getUsdAmount(punishmentDOT.toString(), prices.polkadot.usd)
})}
</div>
</div>
<div className='row justify-center'>
<div className='col-6 burn'>
<Button
variant='btn red-button app-btn'
onClick={onBurn}>
{t('redeem_page.burn')}
</Button>
</div>
</div>
</React.Fragment>
);
}