基于React編寫一個全局Toast的示例代碼
前言
前些日子在做項目的時候,需要封裝一個Toast
組件。我想起之前用過的庫,只要在入口文件中引入就可以在全局中使用,還是很方便的,借這次機會也來實現(xiàn)一下。說起來也算是forwardRef
、useImperativeHanle
和useContext
的實際使用。
- 第一種,使用
forwardRef
和useImperativeHanle
一個是像react-toastify
庫一樣使用,在入口處放置ToastContainer
,然后在代碼中任意地方使用toast("Wow so easy!")
都有提示
import React from 'react'; import { ToastContainer, toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; function App(){ const notify = () => toast("Wow so easy!"); return ( <div> <button onClick={notify}>Notify!</button> <ToastContainer /> </div> ); }
- 第二種,使用
useContext
在入口處放置ToastProvider
,然后在代碼中任意地方使用 const { show } = useToast()
都有提示。忘記什么庫了。
文中就用antd
的message
來模擬一下我們自己寫的Toast
組件。
正文
我們先來了解一下forwardRef
、useImperativeHanle
和useContext
的基本使用。
forwardRef
和 useImperativeHandle
的基本使用
forwardRef
和 useImperativeHandle
,它們通常一起使用,以便在父組件中暴露子組件的特定方法或?qū)傩浴?/p>
forwardRef
,它允許你將父組件的ref
轉(zhuǎn)發(fā)到子組件中的某個 DOM 節(jié)點或其他 React 組件。這樣,父組件就可以訪問子組件的引用,并直接操作它。
useImperativeHandle
是一個自定義 Hook,它允許你自定義通過 forwardRef
暴露給父組件的 ref
值。你可以指定哪些方法
或屬性
被暴露,而不是直接暴露整個 DOM 節(jié)點或組件實例。
下面是一個簡單的例子
import React, { forwardRef, useImperativeHandle, useRef } from 'react'; const ChildComponent = forwardRef((props, ref) => { const inputRef = useRef(null); useImperativeHandle(ref, () => ({ focus: () => { inputRef.current.focus(); }, })); return <input ref={inputRef} {...props} />; }); const ParentComponent = () => { const childRef = useRef(null); const handleClick = () => { childRef.current.focus(); }; return ( <div> <ChildComponent ref={childRef} /> <button onClick={handleClick}>Focus Child Input</button> </div> ); }; export default ParentComponent;
使用forwardRef和useImperativeHanle封裝全局Toast
封裝組件
import React, { createRef, forwardRef, useImperativeHandle } from 'react'; import { Button, message } from 'antd'; const Toast = forwardRef((props, ref) => { const [messageApi, contextHolder] = message.useMessage(); useImperativeHandle(ref, () => ({ show: (msg: string) => { messageApi.info(msg); } })); return <> {contextHolder} </> }) const ToastRef = createRef<{ show: (msg: string) => {} }>(); export const ToastContain = () => { return <Toast ref={ToastRef} /> } export const showToast = (msg: string) => { if (ToastRef.current) { ToastRef.current.show(msg) } };
在入口中引入
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import router from '@/router/index' import reportWebVitals from './reportWebVitals'; import { RouterProvider } from 'react-router-dom'; import ErrorBoundary from './ErrorBoundary'; import { ToastContain } from './components/Toast'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <ToastContain /> <RouterProvider router={router} fallbackElement={<div>準備中</div>} /> </React.StrictMode> ); reportWebVitals();
然后就可以在全局中使用 showToast
方法了
import React from 'react'; import { showToast } from '../../../components/Toast'; export default function Index() { return <> <div onClick={() => { showToast('sadasds') }} > 提示彈窗 </div> </> }
useContext的基本使用
useContext
用于訪問組件樹中某個層級上定義的 Context
。Context
提供了一種在組件之間共享值的方式,而不必通過組件樹的每個層級顯式傳遞 props
。
- 創(chuàng)建 Context
首先,你需要創(chuàng)建一個 Context
對象。這可以通過調(diào)用 React.createContext
來完成。你還可以為默認值提供一個參數(shù),如果 Context
的 Provider
沒有在組件樹中找到,將使用這個默認值。
import React from 'react'; const MyContext = React.createContext('defaultValue');
- 提供 Context
你需要在組件樹中的某個地方提供這個 Context
。這通常在組件的頂層完成,通過使用 MyContext.Provider
組件,并傳遞一個 value
prop
import React from 'react'; import MyComponent from './MyComponent'; import { MyContext } from './MyContext'; function App() { return ( <MyContext.Provider value="Hello from Context"> <MyComponent /> </MyContext.Provider> ); } export default App;
- 使用
useContext
在需要訪問 Context
的組件中,你可以使用 useContext
Hook 來獲取 Context
的當前值
import React, { useContext } from 'react'; import { MyContext } from './MyContext'; function MyComponent() { const contextValue = useContext(MyContext); return <p>Context value: {contextValue}</p>; } export default MyComponent;
使用useContext來封裝全局Toast
封裝組件
import React, { createContext, useCallback, useContext, useState } from 'react'; import { Button, message } from 'antd'; const ToastContext = createContext<any>(null); export const ToastProvider = ({ children }: any) => { const [messageApi, contextHolder] = message.useMessage(); const show = useCallback((msg: string) => { messageApi.info(msg); }, [messageApi]); return ( <ToastContext.Provider value={{ show }}> {children} {contextHolder} </ToastContext.Provider> ); }; export const useToast = () => { const context = useContext(ToastContext); return context; };
在入口處使用
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import router from '@/router/index' import reportWebVitals from './reportWebVitals'; import { RouterProvider } from 'react-router-dom'; import ErrorBoundary from './ErrorBoundary'; import { ToastProvider } from './components/ToastOne'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <ToastProvider> <RouterProvider router={router} fallbackElement={<div>準備中</div>} /> </ToastProvider> </React.StrictMode> );
然后就可以通過useToast
在全局中使用了
import React from 'react'; import { useToast } from '../../../components/ToastOne'; export default function Index() { const { show } = useToast() return <> <div onClick={() => { show('guiyu') }} > 點擊提示 </div> </> }
結(jié)尾
以上就是基于React編寫一個全局Toast的示例代碼的詳細內(nèi)容,更多關(guān)于React編寫全局Toast的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React中useTransition鉤子函數(shù)的使用詳解
React?18的推出標志著React并發(fā)特性的正式到來,其中useTransition鉤子函數(shù)是一個重要的新增功能,下面我們就來學習一下useTransition鉤子函數(shù)的具體使用吧2024-02-02淺析JS中什么是自定義react數(shù)據(jù)驗證組件
我們在做前端表單提交時,經(jīng)常會遇到要對表單中的數(shù)據(jù)進行校驗的問題。這篇文章主要介紹了js中什么是自定義react數(shù)據(jù)驗證組件,需要的朋友可以參考下2018-10-10