pl-fe: limit rerenders
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
d3b5078030
commit
0a253894a6
5 changed files with 37 additions and 25 deletions
|
@ -32,7 +32,7 @@ const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => {
|
|||
{ enabled: !!accountId, transform: normalizeAccount },
|
||||
);
|
||||
|
||||
const meta = useAppSelector((state) => accountId && state.accounts_meta[accountId] || {});
|
||||
const meta = useAppSelector((state) => accountId && state.accounts_meta[accountId]);
|
||||
|
||||
const {
|
||||
relationship,
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
|
||||
import { uploadCompose } from 'pl-fe/actions/compose';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/useAppDispatch';
|
||||
import { useAppSelector } from 'pl-fe/hooks/useAppSelector';
|
||||
import { useCompose } from 'pl-fe/hooks/useCompose';
|
||||
|
||||
import UploadButton from '../components/upload-button';
|
||||
|
||||
|
@ -14,10 +14,7 @@ interface IUploadButtonContainer {
|
|||
|
||||
const UploadButtonContainer: React.FC<IUploadButtonContainer> = ({ composeId }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const { disabled, resetFileKey } = useAppSelector((state) => ({
|
||||
disabled: state.compose.get(composeId)?.is_uploading,
|
||||
resetFileKey: state.compose.get(composeId)?.resetFileKey!,
|
||||
}));
|
||||
const { is_uploading: disabled, resetFileKey } = useCompose(composeId);
|
||||
|
||||
const onSelectFile = (files: FileList, intl: IntlShape) => {
|
||||
dispatch(uploadCompose(composeId, files, intl));
|
||||
|
|
|
@ -3,14 +3,16 @@ import throttle from 'lodash/throttle';
|
|||
import React, { useEffect, useMemo } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { fetchOwnAccounts, logOut, switchAccount } from 'pl-fe/actions/auth';
|
||||
import Account from 'pl-fe/components/account';
|
||||
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
import { useAppDispatch } from 'pl-fe/hooks/useAppDispatch';
|
||||
import { useAppSelector } from 'pl-fe/hooks/useAppSelector';
|
||||
import { useFeatures } from 'pl-fe/hooks/useFeatures';
|
||||
import { makeGetAccount } from 'pl-fe/selectors';
|
||||
import { RootState } from 'pl-fe/store';
|
||||
|
||||
import ThemeToggle from './theme-toggle';
|
||||
|
||||
|
@ -35,15 +37,18 @@ type IMenuItem = {
|
|||
action?: (event: React.MouseEvent) => void;
|
||||
}
|
||||
|
||||
const getAccount = makeGetAccount();
|
||||
|
||||
const getOtherAccounts = createSelector([
|
||||
(state: RootState) => state.auth.users,
|
||||
(state: RootState) => state.entities[Entities.ACCOUNTS]?.store,
|
||||
], (signedAccounts, accountEntities) => signedAccounts.toArray().map(([_, { id }]) => accountEntities?.[id] as AccountEntity).filter(account => account));
|
||||
|
||||
const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const features = useFeatures();
|
||||
const intl = useIntl();
|
||||
|
||||
const authUsers = useAppSelector((state) => state.auth.users);
|
||||
const otherAccounts = useAppSelector((state) => authUsers.map((authUser: any) => getAccount(state, authUser.id)!));
|
||||
const otherAccounts = useAppSelector(getOtherAccounts);
|
||||
|
||||
const handleLogOut = () => {
|
||||
dispatch(logOut());
|
||||
|
@ -66,7 +71,7 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
|||
|
||||
menu.push({ text: renderAccount(account), to: `/@${account.acct}` });
|
||||
|
||||
otherAccounts.forEach((otherAccount: AccountEntity) => {
|
||||
otherAccounts.forEach((otherAccount?: AccountEntity) => {
|
||||
if (otherAccount && otherAccount.id !== account.id) {
|
||||
menu.push({
|
||||
text: renderAccount(otherAccount),
|
||||
|
@ -99,11 +104,11 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
|
|||
))}
|
||||
</>
|
||||
);
|
||||
}, [account, authUsers, features]);
|
||||
}, [account, otherAccounts.length, features]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchOwnAccountThrottled();
|
||||
}, [account.id, authUsers]);
|
||||
}, [account.id, otherAccounts.length]);
|
||||
|
||||
return (
|
||||
<DropdownMenu
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
import { HelmetProvider } from 'react-helmet-async';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { StatProvider } from 'pl-fe/contexts/stat-context';
|
||||
|
@ -26,18 +27,26 @@ store.dispatch(checkOnboardingStatus() as any);
|
|||
|
||||
/** The root React node of the application. */
|
||||
const PlFe: React.FC = () => (
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<StatProvider>
|
||||
<HelmetProvider>
|
||||
<PlFeHead />
|
||||
<PlFeLoad>
|
||||
<PlFeMount />
|
||||
</PlFeLoad>
|
||||
</HelmetProvider>
|
||||
</StatProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<>
|
||||
<Provider store={store}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<StatProvider>
|
||||
<HelmetProvider>
|
||||
<PlFeHead />
|
||||
<PlFeLoad>
|
||||
<PlFeMount />
|
||||
</PlFeLoad>
|
||||
</HelmetProvider>
|
||||
</StatProvider>
|
||||
</QueryClientProvider>
|
||||
</Provider>
|
||||
<div id='toaster'>
|
||||
<Toaster
|
||||
position='top-right'
|
||||
containerClassName='top-4'
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
export { PlFe as default };
|
||||
|
|
|
@ -349,6 +349,7 @@ const makeGetStatusIds = () => createSelector([
|
|||
export {
|
||||
type RemoteInstance,
|
||||
selectAccount,
|
||||
selectAccounts,
|
||||
selectOwnAccount,
|
||||
makeGetAccount,
|
||||
getFilters,
|
||||
|
|
Loading…
Reference in a new issue