Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] feat: 토스트 구현 #608

Merged
merged 22 commits into from
Oct 6, 2023
Merged

[FE] feat: 토스트 구현 #608

merged 22 commits into from
Oct 6, 2023

Conversation

hae-on
Copy link
Collaborator

@hae-on hae-on commented Sep 13, 2023

Issue

✨ 구현한 기능

토스트를 구현하였습니다.
_기록 2023-09-13 오전 10 22 56

_기록 2023-09-13 오전 10 23 15

📢 논의하고 싶은 내용

에러 버전과 기본 버전만 만들었습니다.
추후 상황에 따라 더 추가하거나 리팩터링 하도록 하겠습니다.

🎸 기타

  • 특이 사항이 있으면 작성합니다.

⏰ 일정

  • 추정 시간 : 주말
  • 걸린 시간 : 약 3일

@github-actions
Copy link

Unit Test Results

5 tests   5 ✔️  5s ⏱️
2 suites  0 💤
1 files    0

Results for commit 76ed54a.

Copy link
Collaborator

@Leejin-Yang Leejin-Yang left a comment

Choose a reason for hiding this comment

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

해온의 장인정신 토스트.. 정말 매우 고생했습니다!
알림 메시지가 한결 더 깔끔하게 보이겠네요 👍
코멘트 확인해주세요~

Comment on lines 27 to 29
type ToastStyleProps = Pick<ToastProps, 'isError'>;

const ToastContainer = styled.div<ToastStyleProps & { isAnimating?: boolean }>`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
type ToastStyleProps = Pick<ToastProps, 'isError'>;
const ToastContainer = styled.div<ToastStyleProps & { isAnimating?: boolean }>`
type ToastStyleProps = Pick<ToastProps, 'isError'> & { isAnimating?: boolean };
const ToastContainer = styled.div<ToastStyleProps>`

스타일 프롭스에 isAnimating 타입을 추가하는건 어떤가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

죠습니다

message: string;
}

const Toast = ({ isError, message }: ToastProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

isError에 디폴트 값을 넣어주면 더 좋겠네요!

Comment on lines 12 to 17
useEffect(() => {
setTimeout(() => setIsAnimating(false), 2000);
if (!isAnimating) {
setTimeout(() => clearTimeout(toastTimer.current), 500);
}
}, [isAnimating]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

클린업 함수도 추가해보죠!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

추가 완

@@ -8,7 +8,7 @@ import { RouterProvider } from 'react-router-dom';

import { SvgSprite } from './components/Common';
import router from './router';
import GlobalStyle from './styles';
import GlobalStyle from './styles/globalStyle';
Copy link
Collaborator

Choose a reason for hiding this comment

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

파일 이름을 globalStyle로 바꾼 이유가 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

animation이라는 파일을 추가했는데 index.ts가 있더라구요. 당연히 다른 파일처럼 경로 모아두는 파일이라고 생각했는데 아니여서 헷갈렸습니다. 지금은 global이랑 animation밖에 없는데 하나 더 추가되면 index.ts에 경로를 모아두어야 할 거 같아서 수정했습니다.


export const slideIn = keyframes`
0% {
transform: translateY(-100px);
Copy link
Collaborator

Choose a reason for hiding this comment

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

transform 👍

const useToast = () => {
const [isOpen, setIsOpen] = useState(false);
const [isAnimating, setIsAnimating] = useState(true);
const toastTimer = useRef<NodeJS.Timeout>();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const toastTimer = useRef<NodeJS.Timeout>();
const toastTimer = useRef<number | null>(null);

브라우저 환경에서 동작하니 number로 가고
undefined보다 null로 없다는걸 명시적으로 하는 건 어떤가요??

아래 setTimeout -> window.setTimeout이 되겠네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

얍 수정하였습니다

Copy link
Collaborator

@xodms0309 xodms0309 left a comment

Choose a reason for hiding this comment

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

해온~~ 토스트 컴포넌트 만드느라 정말 수고 많았습니다.
이 컴포넌트에 제가 제안하고 싶은 방법이 있는데요! 저도 장바구니 미션을 할 때 받았던 피드백입니다.
현재 토스트 컴포넌트는 조건부 렌더링을 하고 있는데요, 이 부분을 호출하는 방법으로 써보면 어떨까 싶습니다

if (success) toast.success("토스트 메시지")

이런식으로 쓸 수 있게요!

저희 서비스에서 토스트 메시지는 리뷰 작성 완료했을 때의 성공/실패 여부에 대해 보여지게 될 것 같은데 위와 같이 호출 방법으로 작성하면 query의 onSuccess에서 간단하게 작성이 가능할 것 같습니다!

onSuccess: () => toast.success("리뷰 작성 완료");

이런식으로요! 나머지는 다 굿굿입니다~~👍

Comment on lines 27 to 32
<>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast message="토스트 메세지" />}
</div>
</>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
<>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast message="토스트 메세지" />}
</div>
</>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast message="토스트 메세지" />}
</div>

Comment on lines 46 to 51
<>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast isError message="토스트 메세지" />}
</div>
</>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
<>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast isError message="토스트 메세지" />}
</div>
</>
<div style={{ width: '375px' }}>
<button onClick={handleClick}>토스트 테스트</button>
{isOpen && <Toast isError message="토스트 메세지" />}
</div>

요것들은 fragment로 안감싸도 되겠네용

@github-actions
Copy link

github-actions bot commented Sep 30, 2023

Test Results

2 tests   2 ✔️  0s ⏱️
1 suites  0 💤
1 files    0

Results for commit bd50ecb.

♻️ This comment has been updated with latest results.

@hae-on
Copy link
Collaborator Author

hae-on commented Oct 6, 2023

@xodms0309 @Leejin-Yang

2023-10-06.9.48.39.mov

context를 활용해 토스트를 구현하였습니다.
하나의 토스트를 두고 교체하는 방식으로 하려고 했는데 isAnimating이라는 함수가 제대로 동작하지 않아 하지 못했습니다.
대신 토스트를 배열에 넣고 id로 삭제하는 방식으로 구현하였습니다.

물론 이 방식도 토스트 호출을 마구 갈기면 토스트가 사라질 때 엉망진창으로 사라지는 오류가 있습니다....ㅠ
우리 서비스에서는 그럴일이 없을 거 같아 아직은 나둘 생각입니다!

오랜만에 context를 사용해서 제대로 사용한게 맞나 모르겠네요 확인 부탁드려요!
특히 Toast.tsx를 보면

  const [isShown, setIsShown] = useState(true);

  useEffect(() => {
    setTimeout(() => setIsShown(false), 2000);
    if (!isShown) {
      setTimeout(() => deleteToast(id), 500);
    }
  }, [isShown]);

이 부분을 Context에 옮기고 싶었는데 id를 못받아와서 저기에 뒀습니다...
deleteToast의 Id를 context에서 처리할 수 있으면 context에서 setIsShown랑 deleteToast는 내보내지 않아도 될 거 같은데 방법을 모르겠네요.

toast provider를 어디에 둘 지 몰라서 Index.tsx에 RouterProvider 상위에 감쌌습니다.
이것도 다른 곳을 원하신다면 어디에 둘 지 말해주세요.
끗-

Copy link
Collaborator

@xodms0309 xodms0309 left a comment

Choose a reason for hiding this comment

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

해옹 토스트 굽느라 고생했어요 코멘트 몇 개만 확인해주세요!
그리고 저만 뭔가 토스트 빨리 사라지는 것 같나요?🤔

Comment on lines 31 to 33
<>
<button onClick={handleClick}>토스트 성공</button>
</>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fragment 지워도 될 것 같네용

Comment on lines 47 to 49
<>
<button onClick={handleClick}>토스트 에러</button>
</>
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기도요

@@ -19,6 +19,7 @@ export const HomePage = () => {

return (
<>
<button>하이</button>
Copy link
Collaborator

Choose a reason for hiding this comment

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

하이

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

바이

Comment on lines 61 to 63
{toasts.map((toast) => (
<Toast key={toast.id} id={toast.id} message={toast.message} isError={toast.isError} />
))}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
{toasts.map((toast) => (
<Toast key={toast.id} id={toast.id} message={toast.message} isError={toast.isError} />
))}
{toasts.map(({id, message, isError}) => (
<Toast key={id} id={id} message={message} isError={isError} />
))}

destructing 해서 쓰는게 어떤가요?!


return (
<ToastWrapper isError={isError} isAnimating={isShown}>
<MessageWrapper color={theme.colors.white}>{message}</MessageWrapper>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Text 컴포넌트라서 MessageWrapper보다 Message라고 네이밍 하는게 더 좋을 것 같아요!


const toastAction = {
toast,
setToasts,
Copy link
Collaborator

Choose a reason for hiding this comment

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

얘는 내보냈는데 안 쓰는 것 같아요 맞나요?

Copy link
Collaborator

@Leejin-Yang Leejin-Yang left a comment

Choose a reason for hiding this comment

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

토스트 대장정 수고했어요 해온
이제 진정한 토스트 장인이네요!

Comment on lines +46 to +48
<ToastProvider>
<RouterProvider router={router} fallbackElement={<p>...loading</p>} />
</ToastProvider>
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

Comment on lines 19 to 24
useEffect(() => {
setTimeout(() => setIsShown(false), 2000);
if (!isShown) {
setTimeout(() => deleteToast(id), 500);
}
}, [isShown]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

클린업 함수 작성해주세요~

@hae-on
Copy link
Collaborator Author

hae-on commented Oct 6, 2023

@xodms0309 @Leejin-Yang

2023-10-06.3.20.38.mov

속도 조절했습니다! 대신 저번처럼 위치 바뀌고 삭제되는게 아니라 그 자리에서 삭제 되네요! 참고해주세요~

@hae-on hae-on merged commit a1a27dc into develop Oct 6, 2023
3 checks passed
@hae-on hae-on deleted the feat/issue-587 branch October 6, 2023 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FE] 토스트 구현
3 participants