Recoilを使用したカスタムトーストフックの作成
25171 ワード
緒論
トーストって何?
トーストは特定のイベントに反応し、簡単なフィードバックを短いテキストでUIを提供します.
トーストの実施方法
次のように、特定のイベントの発生状況をステータスとして管理することで、トーストをオフセットできます.
const [isError, setIsError] = useState(false);
...
{ isError && <Toast/> }
スクリーンの移動中、トーストは懸濁しなければなりません.トーストが浮遊する時間の後にアンロードする必要がありますが、トーストが再浮遊する必要がある場合は、アンロードする必要があるプロセスが面倒になります.
グローバル変数としてトーストを管理し,トーストを含む空間もルータの上部に置く.
本稿で紹介する内容
本論文では,上記の考慮事項に基づいて,
Recoil
およびstyled component
を用いてトースト容器アセンブリを実現し,トーストを用いたhookを作製する論理について議論した.Related Pull Request
https://github.com/Neogasogaeseo/Naega-Web/pull/78
本題
Recoil Atomの定義
@stores/toast
import { atom } from 'recoil';
export interface Toast {
id?: string;
content: string;
duration?: number;
bottom?: number;
}
export const toastState = atom<Toast[]>({
key: 'toastState',
default: [],
});
画面に表示されているすべてのトーストを保存する状態を作りました.各ロールは次のようになります.
useToast hookの作成
@hooks/useToast
import { Toast, toastState } from '@stores/toast';
import { getRandomID } from '@utils/etc';
import { useRecoilState } from 'recoil';
export function useToast() {
const [toasts, setToasts] = useRecoilState(toastState);
const removeToast = (toastID: Toast['id']) =>
setToasts((prev) => prev.filter((toast) => toast.id !== toastID));
const fireToast = (toast: Toast) => {
setToasts((prev) => [...prev, { ...toast, id: getRandomID() }]);
setTimeout(() => removeToast(toast.id), 600 + (toast.duration ?? 1000));
};
return { toasts, fireToast };
}
このときidを設定する関数は以下のようになります.@utils/etc
export const getRandomID = () => String(new Date().getTime());
上で作成したstateを操作するためにhookを作成します.toastsは、recoilから受信したコンテンツを返し、toastを追加し、duration後にtoastを削除する
fireToast
という関数を返します.durationに600を加えた理由は、アニメーション表示トーストが消える時間を確保するためだ.
AST ItemとAST Listコンポーネントの実装
@common/Toast/Item
import { Toast } from '@stores/toast';
import { useEffect, useState } from 'react';
import { StToastItem } from './style';
function ToastItem(props: Toast) {
const { content, bottom, duration } = props;
const [isClosing, setIsClosing] = useState(false);
useEffect(() => {
const setExistTimeout = setTimeout(() => {
setIsClosing(true);
clearTimeout(setExistTimeout);
}, duration ?? 1000);
});
return (
<StToastItem bottom={bottom} isClosing={isClosing}>
{content}
</StToastItem>
);
}
export default ToastItem;
toastをアンインストールすると、isClosing
のアニメーションが管理され、duration後にtrueに変換されます.styled componentはisClosing値を受信し、他のアニメーションを提供します.
@common/Toast/Item/style
import styled from 'styled-components';
import { ANIMATION } from '@styles/common/animation';
export const StToastItem = styled.div<{ bottom?: number; isClosing: boolean }>`
position: absolute;
...
bottom: ${({ bottom }) => bottom ?? 26}px;
animation: 0.3s forwards
${({ isClosing }) => (isClosing ? ANIMATION.FADE_OUT : ANIMATION.FADE_IN)};
`;
@common/Toast/List
import { toastState } from '@stores/toast';
import { useRecoilValue } from 'recoil';
import ToastItem from '../Item';
import { StToastList } from './style';
function ToastList() {
const toasts = useRecoilValue(toastState);
return (
<StToastList>
{toasts.map((toast) => (
<ToastItem key={toast.id} {...toast} />
))}
</StToastList>
);
}
export default ToastList;
トーストリストに入れます.この場合、いずれのページも一定の形式で表示しなければならないので、位置決めを与えます.
@common/Toast/List/style
import styled from 'styled-components';
export const StToastList = styled.div`
bottom: 0;
left: 0;
position: fixed;
z-index: 1000;
`;
App.インプラントtsx
App.tsx
import GlobalStyle from '@styles/global';
import Router from '@routes/Router';
import ToastList from '@components/common/Toast/List';
function App() {
return (
<>
<GlobalStyle />
<ToastList />
<Router />
</>
);
}
export default App;
上で実装したToostListを最上位層に入れる.n/a.結論
構成部品での使用
const { fireToast } = useToast();
fireToast({ content:"안녕" });
トーストの生成,消失,アニメーションなどのプロセスは素子内で抽象化されるため,外部素子はfireToast関数を呼び出すだけでよい.このようにcustom hookやrecoilを使うと、トーストが便利に使えます.
Reference
この問題について(Recoilを使用したカスタムトーストフックの作成), 我々は、より多くの情報をここで見つけました https://velog.io/@1106laura/custom-toast-hook-with-recoilテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol