From 10b28406118df21b3a43d9041e92df26feef9b99 Mon Sep 17 00:00:00 2001 From: Harang Date: Thu, 9 Feb 2023 19:56:24 +0900 Subject: [PATCH] =?UTF-8?q?perf:=20tag=20list=EC=97=90=20memo=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EC=97=AC=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=EB=A5=BC=20=EC=A0=81=EC=9A=A9=ED=95=98=EB=9D=BC=20(#6?= =?UTF-8?q?13)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 홈 화면에서 필터링이 적용될 때 불필요한 tag 렌더링 최적화 - 글 작성 시 input 값이 변경될 때 불필요하게 tag가 리렌더링되는 곳 최적화 적용 - profile image에 memo 적용 --- src/components/common/EmptyStateArea.tsx | 4 ++-- src/components/common/ProfileImage.tsx | 4 ++-- src/components/common/SwitchButton.tsx | 24 +++++++++++---------- src/components/common/Tag.tsx | 4 ++-- src/components/home/TagsBar.tsx | 14 ++++++------ src/components/write/TagForm.tsx | 4 ++-- src/components/write/TagList.tsx | 8 +++---- src/containers/write/WriteFormContainer.tsx | 2 +- 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/components/common/EmptyStateArea.tsx b/src/components/common/EmptyStateArea.tsx index 51aa51c6..8e9f22e0 100644 --- a/src/components/common/EmptyStateArea.tsx +++ b/src/components/common/EmptyStateArea.tsx @@ -1,4 +1,4 @@ -import { memo, ReactElement } from 'react'; +import { ReactElement } from 'react'; import styled from '@emotion/styled'; @@ -46,7 +46,7 @@ function EmptyStateArea({ ); } -export default memo(EmptyStateArea); +export default EmptyStateArea; const EmptyStateWrapper = styled.section<{ marginTop: string; }>` display: flex; diff --git a/src/components/common/ProfileImage.tsx b/src/components/common/ProfileImage.tsx index 47abfeb0..e8d5aa0f 100644 --- a/src/components/common/ProfileImage.tsx +++ b/src/components/common/ProfileImage.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import { memo, ReactElement } from 'react'; import Image from 'next/image'; @@ -50,7 +50,7 @@ function ProfileImage({ ); } -export default ProfileImage; +export default memo(ProfileImage); const ProfileAvatarImage = styled(Image)` border-radius: 70%; diff --git a/src/components/common/SwitchButton.tsx b/src/components/common/SwitchButton.tsx index df2ba72e..c772f915 100644 --- a/src/components/common/SwitchButton.tsx +++ b/src/components/common/SwitchButton.tsx @@ -9,17 +9,19 @@ interface Props { defaultChecked: boolean; } -const SwitchButton = ({ onChange, defaultChecked }: Props) => ( - -); +function SwitchButton({ onChange, defaultChecked }: Props) { + return ( + + ); +} export default SwitchButton; diff --git a/src/components/common/Tag.tsx b/src/components/common/Tag.tsx index 5c6c96ff..83ecd01b 100644 --- a/src/components/common/Tag.tsx +++ b/src/components/common/Tag.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import { memo, ReactElement } from 'react'; import { X as CloseSvg } from 'react-feather'; import { useTheme } from '@emotion/react'; @@ -37,7 +37,7 @@ function Tag({ tag, onRemove, onClick }: Props): ReactElement { ); } -export default Tag; +export default memo(Tag); const TagWrapper = styled.div` display: inline-flex; diff --git a/src/components/home/TagsBar.tsx b/src/components/home/TagsBar.tsx index e19c7bdc..2a144eb8 100644 --- a/src/components/home/TagsBar.tsx +++ b/src/components/home/TagsBar.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import { memo, ReactElement, useCallback } from 'react'; import styled from '@emotion/styled'; import { useSetRecoilState } from 'recoil'; @@ -13,23 +13,25 @@ function TagsBar(): ReactElement { const setGroupsCondition = useSetRecoilState(groupsConditionState); + const onClick = useCallback((name: string) => setGroupsCondition((prev) => ({ + ...prev, + tag: name, + })), []); + return ( {tags.map(({ name }) => ( setGroupsCondition((prev) => ({ - ...prev, - tag: name, - }))} + onClick={() => onClick(name)} /> ))} ); } -export default TagsBar; +export default memo(TagsBar); const TagsWrapper = styled.div` height: 36px; diff --git a/src/components/write/TagForm.tsx b/src/components/write/TagForm.tsx index a4aff9d4..0293a657 100644 --- a/src/components/write/TagForm.tsx +++ b/src/components/write/TagForm.tsx @@ -53,10 +53,10 @@ function TagForm({ tags: initialTags, onChange }: Props): ReactElement { actionKeyEvent(e, ['Enter']); }, [actionKeyEvent]); - const handleRemove = (nextTags: string[]) => { + const handleRemove = useCallback((nextTags: string[]) => { setTags(nextTags); onChange(nextTags); - }; + }, [onChange]); useEffect(() => { setTags(initialTags); diff --git a/src/components/write/TagList.tsx b/src/components/write/TagList.tsx index 2406bfde..952c6f4f 100644 --- a/src/components/write/TagList.tsx +++ b/src/components/write/TagList.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import { memo, ReactElement, useCallback } from 'react'; import Tag from '../common/Tag'; @@ -8,11 +8,11 @@ interface Props { } function TagList({ onRemove, tags }: Props): ReactElement { - const handleRemove = (target: string) => { + const handleRemove = useCallback((target: string) => { const nextTags = tags.filter((tag) => tag !== target); onRemove(nextTags); - }; + }, [tags, onRemove]); return ( <> @@ -27,4 +27,4 @@ function TagList({ onRemove, tags }: Props): ReactElement { ); } -export default TagList; +export default memo(TagList); diff --git a/src/containers/write/WriteFormContainer.tsx b/src/containers/write/WriteFormContainer.tsx index 3887a7a6..d047af1f 100644 --- a/src/containers/write/WriteFormContainer.tsx +++ b/src/containers/write/WriteFormContainer.tsx @@ -13,7 +13,7 @@ function WriteFormContainer(): ReactElement | null { const onChangeFields = useCallback((form: Partial) => { changeFields((prevState) => ({ ...prevState, ...form })); - }, [changeFields]); + }, []); if (!user) { return null;