mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
Add memo to components
Add suspense for dynamic import
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import clsx from 'clsx';
|
||||
import useMounted from 'lib/hooks/useMounted';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { memo } from 'react';
|
||||
import { FiMoon, FiSun } from 'react-icons/fi';
|
||||
|
||||
const DarkModeBtn = () => {
|
||||
@ -35,4 +36,4 @@ const DarkModeBtn = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default DarkModeBtn;
|
||||
export default memo(DarkModeBtn);
|
@ -1,3 +1,4 @@
|
||||
import { memo } from 'react';
|
||||
import { FiGithub } from 'react-icons/fi';
|
||||
|
||||
const nowDay = new Date().getFullYear();
|
||||
@ -25,4 +26,4 @@ const Footer = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
export default memo(Footer);
|
@ -3,7 +3,7 @@ import { DocSearch } from '@docsearch/react';
|
||||
import clsx from 'clsx';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import { FiMenu } from 'react-icons/fi';
|
||||
|
||||
const DarkModeBtn = dynamic(() => import('components/DarkModeBtn'));
|
||||
@ -162,4 +162,4 @@ const HeadBar = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default HeadBar;
|
||||
export default memo(HeadBar);
|
@ -1,6 +1,7 @@
|
||||
import Link from 'next/link';
|
||||
import { Post } from 'types';
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
|
||||
interface Props {
|
||||
post: Post;
|
||||
@ -50,4 +51,4 @@ const PostCard = ({ post }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PostCard;
|
||||
export default memo(PostCard);
|
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import { ButtonHTMLAttributes, DetailedHTMLProps } from 'react';
|
||||
import { ButtonHTMLAttributes, DetailedHTMLProps, memo } from 'react';
|
||||
|
||||
export type ButtonProps = {
|
||||
children: React.ReactNode;
|
||||
@ -36,4 +36,4 @@ const Button = ({ children, ...rest }: ButtonProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Button;
|
||||
export default memo(Button);
|
@ -1,7 +1,7 @@
|
||||
import clsx from 'clsx';
|
||||
import useInView from 'lib/hooks/useInView';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import RUALoading from './loading/RUALoading';
|
||||
|
||||
const partten =
|
||||
@ -64,4 +64,4 @@ const RUACodeSandbox = ({ url }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default RUACodeSandbox;
|
||||
export default memo(RUACodeSandbox);
|
@ -1,7 +1,7 @@
|
||||
import clsx from 'clsx';
|
||||
import useInView from 'lib/hooks/useInView';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { memo, useEffect, useState } from 'react';
|
||||
import RUALoading from './loading/RUALoading';
|
||||
|
||||
export const commonClass = clsx(
|
||||
@ -63,15 +63,14 @@ const RUACodepen = ({ defaultTab, url }: Props) => {
|
||||
'transition-all h-[402px]',
|
||||
'border-none',
|
||||
'absolute top-1/2 left-1/2',
|
||||
'-translate-x-1/2 -translate-y-1/2'
|
||||
'-translate-x-1/2 -translate-y-1/2',
|
||||
'overflow-hidden'
|
||||
)}
|
||||
style={{
|
||||
width: 'calc(100% + 2px)',
|
||||
}}
|
||||
onLoad={handleLoad}
|
||||
scrolling="no"
|
||||
src={src}
|
||||
frameBorder="no"
|
||||
loading="lazy"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
@ -81,4 +80,4 @@ const RUACodepen = ({ defaultTab, url }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default RUACodepen;
|
||||
export default memo(RUACodepen);
|
@ -1,6 +1,6 @@
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import { DetailedHTMLProps, HTMLAttributes } from 'react';
|
||||
import { DetailedHTMLProps, HTMLAttributes, memo } from 'react';
|
||||
|
||||
const Button = dynamic(() => import('components/RUA/Button'));
|
||||
|
||||
@ -59,4 +59,4 @@ const RUAPagination = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default RUAPagination;
|
||||
export default memo(RUAPagination);
|
@ -1,5 +1,6 @@
|
||||
import { Sandpack, SandpackProps } from '@codesandbox/sandpack-react';
|
||||
import { useTheme } from 'next-themes';
|
||||
import { memo } from 'react';
|
||||
|
||||
interface Props extends SandpackProps {}
|
||||
|
||||
@ -19,4 +20,4 @@ const RUASandpack = ({ ...rest }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default RUASandpack;
|
||||
export default memo(RUASandpack);
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
|
||||
const PostCardLoading = () => {
|
||||
@ -26,4 +26,4 @@ const PostCardLoading = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PostCardLoading;
|
||||
export default memo(PostCardLoading);
|
@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { memo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import loadingImage from 'public/images/img/mona-loading-default.gif';
|
||||
import loadingImageDimmed from 'public/images/img/mona-loading-dimmed.gif';
|
||||
@ -34,4 +34,4 @@ const RUALoading = ({ className: classNames }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default RUALoading;
|
||||
export default memo(RUALoading);
|
@ -1,4 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import { memo } from 'react';
|
||||
import styles from './VercelLoading.module.css';
|
||||
|
||||
const VercelLoading = () => {
|
||||
@ -40,4 +41,4 @@ const VercelLoading = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default VercelLoading;
|
||||
export default memo(VercelLoading);
|
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
export type ItemProps = {
|
||||
value: string | number;
|
||||
@ -16,4 +16,4 @@ const TabItem = ({ showContent, children }: ItemProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default TabItem;
|
||||
export default memo(TabItem);
|
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import React, { useState } from 'react';
|
||||
import React, { memo, useState } from 'react';
|
||||
import { ItemProps } from './TabItem';
|
||||
|
||||
type Props = {
|
||||
@ -56,4 +56,4 @@ const Tab = ({ defaultValue, children }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Tab;
|
||||
export default memo(Tab);
|
@ -1,5 +1,6 @@
|
||||
import clsx from 'clsx';
|
||||
import Button from 'components/RUA/Button';
|
||||
import { memo } from 'react';
|
||||
import { FiChevronUp } from 'react-icons/fi';
|
||||
|
||||
const BackToTop = () => {
|
||||
@ -15,7 +16,7 @@ const BackToTop = () => {
|
||||
<Button
|
||||
onClick={handleBack}
|
||||
className={clsx(
|
||||
'!px-3 fixed',
|
||||
'!p-3 fixed',
|
||||
'right-4 bottom-4',
|
||||
'lg:right-8 lg:bottom-8'
|
||||
)}
|
||||
@ -26,4 +27,4 @@ const BackToTop = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default BackToTop;
|
||||
export default memo(BackToTop);
|
@ -4,9 +4,10 @@ import dayjs from 'dayjs';
|
||||
import { GistData } from 'lib/fetcher';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Link from 'next/link';
|
||||
import { memo, Suspense } from 'react';
|
||||
|
||||
const GistsCode = dynamic(() => import('components/gists/GistsCode'), {
|
||||
loading: () => <Loading className="h-[300px]" />,
|
||||
suspense: true,
|
||||
});
|
||||
|
||||
type Props = {
|
||||
@ -37,7 +38,9 @@ const FileContent = ({ gists }: Props) => {
|
||||
{/* Description */}
|
||||
<p className="text-gray-500">{g.description}</p>
|
||||
|
||||
<GistsCode file={g.files[f]} />
|
||||
<Suspense fallback={<Loading className="h-[300px]" />}>
|
||||
<GistsCode file={g.files[f]} />
|
||||
</Suspense>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@ -47,4 +50,4 @@ const FileContent = ({ gists }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default FileContent;
|
||||
export default memo(FileContent);
|
@ -1,6 +1,6 @@
|
||||
import rehypePrism from '@mapbox/rehype-prism';
|
||||
import clsx from 'clsx';
|
||||
import { createElement, Fragment } from 'react';
|
||||
import { createElement, Fragment, memo } from 'react';
|
||||
import rehypeReact from 'rehype-react';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkParse from 'remark-parse';
|
||||
@ -76,4 +76,4 @@ const GistsCode = ({ file, showFileName = false }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default GistsCode;
|
||||
export default memo(GistsCode);
|
@ -2,6 +2,7 @@ import clsx from 'clsx';
|
||||
import { GetUser } from 'lib/fetcher';
|
||||
import Image from 'next/image';
|
||||
import avatar from 'public/images/img/avatar.svg';
|
||||
import { memo } from 'react';
|
||||
import { FiLink, FiMail, FiTwitter } from 'react-icons/fi';
|
||||
|
||||
type Props = {
|
||||
@ -79,4 +80,4 @@ const UserInfo = ({ user }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default UserInfo;
|
||||
export default memo(UserInfo);
|
@ -1,4 +1,4 @@
|
||||
import { AnchorHTMLAttributes, forwardRef } from 'react';
|
||||
import { AnchorHTMLAttributes, forwardRef, memo } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { FiExternalLink } from 'react-icons/fi';
|
||||
|
||||
@ -33,6 +33,7 @@ const Anchor = forwardRef<HTMLAnchorElement, Props>(
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Anchor.displayName = 'Anchor';
|
||||
|
||||
export default Anchor;
|
||||
export default memo(Anchor);
|
@ -1,5 +1,6 @@
|
||||
import clsx from 'clsx';
|
||||
import NextImage, { ImageProps } from 'next/image';
|
||||
import { memo } from 'react';
|
||||
|
||||
interface Props extends ImageProps {}
|
||||
|
||||
@ -18,4 +19,4 @@ const Image = ({ alt, ...rest }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Image;
|
||||
export default memo(Image);
|
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import { ReactNode } from 'react';
|
||||
import { memo, ReactNode } from 'react';
|
||||
import { FiExternalLink } from 'react-icons/fi';
|
||||
|
||||
interface Props {
|
||||
@ -26,4 +26,4 @@ const Anchor = ({ children, external = true }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Anchor;
|
||||
export default memo(Anchor);
|
@ -1,8 +1,13 @@
|
||||
import clsx from 'clsx';
|
||||
import CopyButton from 'components/post/CopyButton';
|
||||
import useCopyToClipboard from 'lib/hooks/useCopyToClipboard';
|
||||
import { DetailedHTMLProps, HTMLAttributes, lazy, useRef } from 'react';
|
||||
|
||||
const CopyButton = lazy(() => import('components/post/CopyButton'));
|
||||
import {
|
||||
DetailedHTMLProps,
|
||||
HTMLAttributes,
|
||||
memo,
|
||||
useCallback,
|
||||
useRef,
|
||||
} from 'react';
|
||||
|
||||
type Props = {} & DetailedHTMLProps<
|
||||
HTMLAttributes<HTMLPreElement>,
|
||||
@ -14,11 +19,11 @@ const Pre = ({ ...rest }: Props) => {
|
||||
|
||||
const preRef = useRef<HTMLPreElement>(null);
|
||||
const { copy } = useCopyToClipboard();
|
||||
const handleCopy = () => {
|
||||
const handleCopy = useCallback(() => {
|
||||
if (!preRef.current) throw new Error('Can not access pre element.');
|
||||
if (preRef.current.textContent == null) return;
|
||||
copy(preRef.current.textContent);
|
||||
};
|
||||
}, [copy]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -34,4 +39,4 @@ const Pre = ({ ...rest }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Pre;
|
||||
export default memo(Pre);
|
@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import { useState } from 'react';
|
||||
import { memo, useState } from 'react';
|
||||
import styles from './CopytButton.module.css';
|
||||
|
||||
export type CopyButtonProps = {
|
||||
@ -64,4 +64,4 @@ const CopyButton = ({ onCopy: onClick }: CopyButtonProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default CopyButton;
|
||||
export default memo(CopyButton);
|
@ -1,52 +1,27 @@
|
||||
import Giscus from '@giscus/react';
|
||||
import { useTheme } from 'next-themes';
|
||||
import useInView from 'lib/hooks/useInView';
|
||||
import Image from 'next/image';
|
||||
import { memo } from 'react';
|
||||
|
||||
const PostComment = () => {
|
||||
const { systemTheme, theme } = useTheme();
|
||||
const currentTheme = theme === 'system' ? systemTheme : theme;
|
||||
|
||||
const { ref, inView } = useInView();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex justify-center select-none">
|
||||
{currentTheme === 'dark' ? (
|
||||
<Image
|
||||
src="/images/img/comment-line-dark.svg"
|
||||
width={300}
|
||||
height={150}
|
||||
alt=""
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/images/img/comment-line.svg"
|
||||
width={300}
|
||||
height={150}
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mt-4" ref={ref}>
|
||||
{inView && (
|
||||
<Giscus
|
||||
repo="DefectingCat/DefectingCat.github.io"
|
||||
repoId="MDEwOlJlcG9zaXRvcnkyMzk5MTUyNzk="
|
||||
categoryId="DIC_kwDODkzRD84B_43T"
|
||||
category="Announcements"
|
||||
mapping="pathname"
|
||||
reactionsEnabled="1"
|
||||
emitMetadata="0"
|
||||
theme={currentTheme === 'dark' ? 'dark_dimmed' : 'light'}
|
||||
loading="lazy"
|
||||
inputPosition="top"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Giscus
|
||||
repo="DefectingCat/DefectingCat.github.io"
|
||||
repoId="MDEwOlJlcG9zaXRvcnkyMzk5MTUyNzk="
|
||||
categoryId="DIC_kwDODkzRD84B_43T"
|
||||
category="Announcements"
|
||||
mapping="pathname"
|
||||
reactionsEnabled="1"
|
||||
emitMetadata="0"
|
||||
theme={currentTheme === 'dark' ? 'dark_dimmed' : 'light'}
|
||||
loading="lazy"
|
||||
inputPosition="top"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default PostComment;
|
||||
export default memo(PostComment);
|
32
components/post/PostCommnetLine.tsx
Normal file
32
components/post/PostCommnetLine.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import { useTheme } from 'next-themes';
|
||||
import Image from 'next/image';
|
||||
import { memo } from 'react';
|
||||
|
||||
const PostCommnetLine = () => {
|
||||
const { systemTheme, theme } = useTheme();
|
||||
const currentTheme = theme === 'system' ? systemTheme : theme;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex justify-center select-none">
|
||||
{currentTheme === 'dark' ? (
|
||||
<Image
|
||||
src="/images/img/comment-line-dark.svg"
|
||||
width={300}
|
||||
height={150}
|
||||
alt=""
|
||||
/>
|
||||
) : (
|
||||
<Image
|
||||
src="/images/img/comment-line.svg"
|
||||
width={300}
|
||||
height={150}
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(PostCommnetLine);
|
@ -1,7 +1,7 @@
|
||||
import clsx from 'clsx';
|
||||
import Anchor from 'components/mdx/Anchor';
|
||||
import { SingleToc } from 'lib/utils';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { Fragment, memo, useState } from 'react';
|
||||
import { FiChevronDown } from 'react-icons/fi';
|
||||
import styles from './PostToc.module.css';
|
||||
|
||||
@ -77,4 +77,4 @@ const PostToc = ({ toc, tocLength }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PostToc;
|
||||
export default memo(PostToc);
|
@ -1,15 +0,0 @@
|
||||
import useMounted from 'lib/hooks/useMounted';
|
||||
|
||||
const SlideToc = () => {
|
||||
const { mounted } = useMounted();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex justify-end">
|
||||
<div className="toc"></div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SlideToc;
|
Reference in New Issue
Block a user