UNPKG

mh-rn-component

Version:

142 lines (134 loc) 3.55 kB
import React, { createContext, MutableRefObject, useState, useMemo, useContext, useCallback } from 'react' import Toast, { Props } from './index' import { ToastType, VisibleToastsType, ToastContextType, ToastList } from "./types" // 创建一个createContext const ToastContext = createContext<ToastContextType>({ toastList: {}, visibleToasts: {}, setToast: () => { }, hideToast: () => { }, hideAll: () => { }, loading: () => { } }); // 组件调用Context const CustomToast = () => { const { toastList, visibleToasts, hideToast } = useContext(ToastContext) const toastListIds = () => { return Object.keys(visibleToasts) } return (<> { toastListIds().map((id) => { return (<Toast key={id} onChange={() => hideToast(id)} show={visibleToasts[id]} {...toastList[id]}></Toast>) }) } </>) } // 组件调用Context export const ToastProvider = ({ children }: { children: any }) => { const [toastList, setToastList] = useState<ToastList>({}) const [visibleToasts, setVisibleToasts] = useState<VisibleToastsType>({}); const toastIndex = React.useRef(7000); const hideToast = useCallback( (id: any) => { setVisibleToasts((prev) => { return { ...prev, [id]: false } }) }, [setVisibleToasts]) const hideAll = useCallback(() => { setVisibleToasts({}) }, [setVisibleToasts]) const setToast = useCallback( (props: ToastType): number => { const { id = toastIndex.current++, ...rest } = props setToastList((prev) => { return { ...prev, [id]: { id, ...rest } } }) setVisibleToasts((prev) => { return { ...prev, [id]: true } }) return id }, [toastList, visibleToasts, hideToast] ) const loading = useCallback( (props: ToastType): number => { const { id = toastIndex.current++, ...rest } = props setToastList((prev) => { return { ...prev, [id]: { id, icon: "loading1", duration: 0, loading: true, ...rest } } }) setVisibleToasts((prev) => { return { ...prev, [id]: true } }) return id }, [toastList, visibleToasts, hideToast] ) const contextValue = useMemo(() => { return { toastList, visibleToasts, setToast, hideToast, hideAll, loading } }, [toastList, visibleToasts, setToast, hideToast, hideAll, loading]) return ( <ToastContext.Provider value={contextValue}> {children} <CustomToast></CustomToast> </ToastContext.Provider> ) } export const useToast = () => { const { setToast, hideToast, hideAll, loading } = React.useContext( ToastContext ); const toast = useMemo( () => ({ show: setToast, close: hideToast, closeAll: hideAll, loading: loading }), [setToast, hideToast, hideAll, loading] ); return toast; } //!这部分和ref相关的 export type IToastService = ReturnType<typeof useToast>; export const ToastRef = React.createRef<IToastService>() as MutableRefObject<IToastService>; export const _Toast: IToastService = { show: (props: Props) => ToastRef.current?.show(props), close: (id: any) => ToastRef.current?.close(id), closeAll: () => ToastRef.current?.closeAll(), loading: (props: Props) => ToastRef.current?.show(props), // isActive: (id: any) => ToastRef.current?.isActive(id), };