Skip to content

Commit

Permalink
feat: migrate some hooks to usehooks-ts (#2978)
Browse files Browse the repository at this point in the history
* chore: use useUpdateEffect

* chore: migrate useDebounce to usehooks-ts

* chore: migrate useOnClickOutside to usehooks-ts

* chore: migrate useIsMounted to usehooks-ts

* chore: migrate to useEffectOnce
  • Loading branch information
bigint committed May 31, 2023
1 parent 17b322a commit de51f9b
Show file tree
Hide file tree
Showing 54 changed files with 194 additions and 263 deletions.
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"tlds": "^1.238.0",
"ui": "workspace:*",
"use-resize-observer": "^9.1.0",
"usehooks-ts": "^2.9.1",
"uuid": "^9.0.0",
"viem": "^0.3.19",
"wagmi": "^1.0.9",
Expand Down
10 changes: 4 additions & 6 deletions apps/web/src/components/Common/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ import { useUserProfilesQuery } from 'lens';
import Head from 'next/head';
import { useTheme } from 'next-themes';
import type { FC, ReactNode } from 'react';
import { useEffect } from 'react';
import { Toaster } from 'react-hot-toast';
import { CHAIN_ID } from 'src/constants';
import { useAppPersistStore, useAppStore } from 'src/store/app';
import { useIsMounted, useUpdateEffect } from 'usehooks-ts';
import { useAccount, useDisconnect, useNetwork } from 'wagmi';

import GlobalModals from '../Shared/GlobalModals';
import Loading from '../Shared/Loading';
import Navbar from '../Shared/Navbar';
import useIsMounted from '../utils/hooks/useIsMounted';
import { useDisconnectXmtp } from '../utils/hooks/useXmtpClient';

interface LayoutProps {
Expand All @@ -32,7 +31,7 @@ const Layout: FC<LayoutProps> = ({ children }) => {
const profileId = useAppPersistStore((state) => state.profileId);
const setProfileId = useAppPersistStore((state) => state.setProfileId);

const { mounted } = useIsMounted();
const isMounted = useIsMounted();
const { address } = useAccount();
const { chain } = useNetwork();
const { disconnect } = useDisconnect();
Expand Down Expand Up @@ -86,12 +85,11 @@ const Layout: FC<LayoutProps> = ({ children }) => {
}
};

useEffect(() => {
useUpdateEffect(() => {
validateAuthentication();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [address, chain, disconnect, profileId]);

if (loading || !mounted) {
if (loading || !isMounted()) {
return <Loading />;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import FingerprintJS from '@fingerprintjs/fingerprintjs';
import type { FC } from 'react';
import { useEffect } from 'react';
import { useFingerprintStore } from 'src/store/fingerprint';
import { useEffectOnce } from 'usehooks-ts';

const LeafwatchProvider: FC = () => {
const setFingerprint = useFingerprintStore((state) => state.setFingerprint);
Expand All @@ -12,10 +12,10 @@ const LeafwatchProvider: FC = () => {
setFingerprint(visitorId);
};

useEffect(() => {
useEffectOnce(() => {
saveFingerprint();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
});

return null;
};

Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/Composer/Actions/Attachment.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import MenuTransition from '@components/Shared/MenuTransition';
import useOnClickOutside from '@components/utils/hooks/useOnClickOutside';
import useUploadAttachments from '@components/utils/hooks/useUploadAttachments';
import { Menu } from '@headlessui/react';
import {
Expand All @@ -20,6 +19,7 @@ import { Fragment, useId, useRef, useState } from 'react';
import toast from 'react-hot-toast';
import { usePublicationStore } from 'src/store/publication';
import { Spinner, Tooltip } from 'ui';
import { useOnClickOutside } from 'usehooks-ts';
const Attachment: FC = () => {
const attachments = usePublicationStore((state) => state.attachments);
const isUploading = usePublicationStore((state) => state.isUploading);
Expand Down
27 changes: 9 additions & 18 deletions apps/web/src/components/Composer/Actions/Giphy/GifSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useDebounce } from '@components/utils/hooks/useDebounce';
import type { ICategory } from '@giphy/js-fetch-api';
import { GiphyFetch } from '@giphy/js-fetch-api';
import type { IGif } from '@giphy/js-types';
import { Grid } from '@giphy/react-components';
import { t, Trans } from '@lingui/macro';
import type { ChangeEvent, Dispatch, FC } from 'react';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { Input } from 'ui';
import { useDebounce, useEffectOnce } from 'usehooks-ts';

const giphyFetch = new GiphyFetch('sXpGFDGZs0Dv1mmNFvYaGUvYwKX0PWIh');

Expand All @@ -20,8 +20,8 @@ const GifSelector: FC<GifSelectorProps> = ({
setGifAttachment
}) => {
const [categories, setCategories] = useState<ICategory[]>([]);
const [debouncedGifInput, setDebouncedGifInput] = useState('');
const [searchText, setSearchText] = useState('');
const debouncedGifInput = useDebounce<string>(searchText, 500);

const fetchGiphyCategories = async () => {
const { data } = await giphyFetch.categories();
Expand All @@ -31,30 +31,21 @@ const GifSelector: FC<GifSelectorProps> = ({

const onSelectGif = (item: IGif) => {
setGifAttachment(item);
setDebouncedGifInput('');
setSearchText('');
setShowModal(false);
};

useDebounce(
() => {
setSearchText(debouncedGifInput);
},
1000,
[debouncedGifInput]
);

useEffect(() => {
useEffectOnce(() => {
fetchGiphyCategories();
}, []);
});

const fetchGifs = (offset: number) => {
return giphyFetch.search(searchText, { offset, limit: 10 });
return giphyFetch.search(debouncedGifInput, { offset, limit: 10 });
};

const handleSearch = (evt: ChangeEvent<HTMLInputElement>) => {
const keyword = evt.target.value;
setDebouncedGifInput(keyword);
setSearchText(keyword);
};

return (
Expand All @@ -63,7 +54,7 @@ const GifSelector: FC<GifSelectorProps> = ({
<Input
type="text"
placeholder={t`Search for GIFs`}
value={debouncedGifInput}
value={searchText}
onChange={handleSearch}
/>
</div>
Expand All @@ -90,7 +81,7 @@ const GifSelector: FC<GifSelectorProps> = ({
type="button"
key={category.name_encoded}
className="relative flex outline-none"
onClick={() => setDebouncedGifInput(category.name)}
onClick={() => setSearchText(category.name)}
>
<img
className="h-32 w-full cursor-pointer object-cover"
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/components/Composer/ChooseThumbnail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { toast } from 'react-hot-toast';
import { usePublicationStore } from 'src/store/publication';
import type { MediaSetWithoutOnChain } from 'src/types';
import { Spinner } from 'ui';
import { useUpdateEffect } from 'usehooks-ts';

const DEFAULT_THUMBNAIL_INDEX = 0;
export const THUMBNAIL_GENERATE_COUNT = 4;
Expand Down Expand Up @@ -98,9 +99,8 @@ const ChooseThumbnail: FC = () => {
}
};

useEffect(() => {
useUpdateEffect(() => {
onSelectThumbnail(selectedThumbnailIndex);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedThumbnailIndex]);

useEffect(() => {
Expand Down
10 changes: 5 additions & 5 deletions apps/web/src/components/Composer/NewPublication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import getTags from 'lib/getTags';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import type { FC } from 'react';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import toast from 'react-hot-toast';
import { OptmisticPublicationType } from 'src/enums';
import { useAccessSettingsStore } from 'src/store/access-settings';
Expand All @@ -81,6 +81,7 @@ import { useTransactionPersistStore } from 'src/store/transaction';
import { PUBLICATION } from 'src/tracking';
import type { NewLensterAttachment } from 'src/types';
import { Button, Card, ErrorMessage, Spinner } from 'ui';
import { useEffectOnce, useUpdateEffect } from 'usehooks-ts';
import { v4 as uuid } from 'uuid';
import { useContractWrite, usePublicClient, useSignTypedData } from 'wagmi';

Expand Down Expand Up @@ -260,16 +261,15 @@ const NewPublication: FC<NewPublicationProps> = ({ publication }) => {
errorToast(error);
};

useEffect(() => {
useUpdateEffect(() => {
setPublicationContentError('');
}, [audioPublication]);

useEffect(() => {
useEffectOnce(() => {
editor.update(() => {
$convertFromMarkdownString(publicationContent);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
});

const generateOptimisticPublication = ({
txHash,
Expand Down
7 changes: 3 additions & 4 deletions apps/web/src/components/Composer/Post/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import formatHandle from 'lib/formatHandle';
import getAvatar from 'lib/getAvatar';
import { useRouter } from 'next/router';
import type { FC } from 'react';
import { useEffect } from 'react';
import { useAppStore } from 'src/store/app';
import { usePublicationStore } from 'src/store/publication';
import { Card, Image, Modal } from 'ui';
import { useEffectOnce } from 'usehooks-ts';

import NewPublication from '../NewPublication';

Expand All @@ -28,7 +28,7 @@ const NewPost: FC = () => {
setShowNewPostModal(true);
};

useEffect(() => {
useEffectOnce(() => {
if (isReady && query.text) {
const { text, url, via, hashtags } = query;
let processedHashtags;
Expand All @@ -47,8 +47,7 @@ const NewPost: FC = () => {
setShowNewPostModal(true);
setPublicationContent(content);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
});

return (
<Card className="space-y-3 p-5">
Expand Down
7 changes: 4 additions & 3 deletions apps/web/src/components/Explore/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import type { PublicationMainFocus } from 'lens';
import { PublicationSortCriteria } from 'lens';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { useAppStore } from 'src/store/app';
import { EXPLORE, PAGEVIEW } from 'src/tracking';
import { GridItemEight, GridItemFour, GridLayout } from 'ui';
import { useEffectOnce } from 'usehooks-ts';

import Feed from './Feed';
import FeedType from './FeedType';
Expand All @@ -29,9 +30,9 @@ const Explore: NextPage = () => {
FeatureFlag.TrendingWidget
);

useEffect(() => {
useEffectOnce(() => {
Leafwatch.track(PAGEVIEW, { page: 'explore' });
}, []);
});

const tabs = [
{ name: t`For you`, type: PublicationSortCriteria.CuratedProfiles },
Expand Down
5 changes: 3 additions & 2 deletions apps/web/src/components/Home/EnableMessages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import clsx from 'clsx';
import { XMTP_ENV } from 'data/constants';
import { useRouter } from 'next/router';
import type { FC } from 'react';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { useAppStore } from 'src/store/app';
import { Button, Card } from 'ui';
import { useUpdateEffect } from 'usehooks-ts';

const EnableMessages: FC = () => {
const currentProfile = useAppStore((state) => state.currentProfile);
Expand All @@ -19,7 +20,7 @@ const EnableMessages: FC = () => {
push('/messages');
};

useEffect(() => {
useUpdateEffect(() => {
const fetchCanMessage = async () => {
const isMessagesEnabled = await Client.canMessage(
currentProfile?.ownedBy,
Expand Down
7 changes: 4 additions & 3 deletions apps/web/src/components/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import ExploreFeed from '@components/Explore/Feed';
import Footer from '@components/Shared/Footer';
import { Leafwatch } from '@lib/leafwatch';
import type { NextPage } from 'next';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { useAppStore } from 'src/store/app';
import { PAGEVIEW } from 'src/tracking';
import { GridItemEight, GridItemFour, GridLayout } from 'ui';
import { useEffectOnce } from 'usehooks-ts';

import EnableDispatcher from './EnableDispatcher';
import EnableMessages from './EnableMessages';
Expand All @@ -25,9 +26,9 @@ const Home: NextPage = () => {
'TIMELINE'
);

useEffect(() => {
useEffectOnce(() => {
Leafwatch.track(PAGEVIEW, { page: 'home' });
}, []);
});

return (
<>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/components/Messages/Composer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import useWindowSize from '@components/utils/hooks/useWindowSize';
import { ArrowRightIcon, PhotographIcon } from '@heroicons/react/outline';
import { XIcon } from '@heroicons/react/solid';
import { Leafwatch } from '@lib/leafwatch';
Expand All @@ -9,7 +8,7 @@ import { ContentTypeText } from '@xmtp/xmtp-js';
import { MIN_WIDTH_DESKTOP } from 'data/constants';
import sanitizeDStorageUrl from 'lib/sanitizeDStorageUrl';
import type { ChangeEvent, FC } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useRef, useState } from 'react';
import toast from 'react-hot-toast';
import {
useAttachmentCachePersistStore,
Expand All @@ -18,6 +17,7 @@ import {
import { useMessagePersistStore } from 'src/store/message';
import { MESSAGES } from 'src/tracking';
import { Button, Input, Spinner } from 'ui';
import { useUpdateEffect, useWindowSize } from 'usehooks-ts';
import type {
Attachment as TAttachment,
RemoteAttachment
Expand Down Expand Up @@ -160,7 +160,7 @@ const Composer: FC<ComposerProps> = ({
setSending(false);
};

useEffect(() => {
useUpdateEffect(() => {
setMessage(unsentMessage ?? '');
}, [unsentMessage]);

Expand Down
7 changes: 4 additions & 3 deletions apps/web/src/components/Messages/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import sanitizeDisplayName from 'lib/sanitizeDisplayName';
import type { NextPage } from 'next';
import { useRouter } from 'next/router';
import type { FC } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useState } from 'react';
import Custom404 from 'src/pages/404';
import { useAppStore } from 'src/store/app';
import { useMessageStore } from 'src/store/message';
import { PAGEVIEW } from 'src/tracking';
import { Card, GridItemEight, GridLayout } from 'ui';
import { useEffectOnce } from 'usehooks-ts';

import Composer from './Composer';
import MessagesList from './MessagesList';
Expand Down Expand Up @@ -115,9 +116,9 @@ const MessagePage: NextPage = () => {
query: { conversationKey }
} = useRouter();

useEffect(() => {
useEffectOnce(() => {
Leafwatch.track(PAGEVIEW, { page: 'conversation' });
}, []);
});

// Need to have a login page for when there is no currentProfileId
if (
Expand Down
Loading

2 comments on commit de51f9b

@vercel
Copy link

@vercel vercel bot commented on de51f9b May 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

prerender – ./apps/prerender

prerender-git-main-lenster.vercel.app
prerender.lenster.xyz
prerender-lenster.vercel.app

@vercel
Copy link

@vercel vercel bot commented on de51f9b May 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

web – ./apps/web

lenster.vercel.app
web-git-main-lenster.vercel.app
web-lenster.vercel.app
lenster.xyz

Please sign in to comment.