翼度科技»论坛 编程开发 JavaScript 查看内容

基于React编写一个全局Toast的示例代码

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
前言

前些日子在做项目的时候,需要封装一个
  1. Toast
复制代码
组件。我想起之前用过的库,只要在入口文件中引入就可以在全局中使用,还是很方便的,借这次机会也来实现一下。说起来也算是
  1. forwardRef
复制代码
  1. useImperativeHanle
复制代码
  1. useContext
复制代码
的实际使用。

  • 第一种,使用
    1. forwardRef
    复制代码
    1. useImperativeHanle
    复制代码
一个是像
  1. react-toastify
复制代码
库一样使用,在入口处放置
  1. ToastContainer
复制代码
,然后在代码中任意地方使用
  1. toast("Wow so easy!")
复制代码
都有提示
  1.   import React from 'react';

  2.   import { ToastContainer, toast } from 'react-toastify';
  3.   import 'react-toastify/dist/ReactToastify.css';
  4.   
  5.   function App(){
  6.     const notify = () => toast("Wow so easy!");

  7.     return (
  8.       <div>
  9.         <button onClick={notify}>Notify!</button>
  10.         <ToastContainer />
  11.       </div>
  12.     );
  13.   }
复制代码

  • 第二种,使用
    1. useContext
    复制代码
在入口处放置
  1. ToastProvider
复制代码
,然后在代码中任意地方使用
  1. const { show } = useToast()
复制代码
都有提示。忘记什么库了。
文中就用
  1. antd
复制代码
  1. message
复制代码
来模拟一下我们自己写的
  1. Toast
复制代码
组件。

正文

我们先来了解一下
  1. forwardRef
复制代码
  1. useImperativeHanle
复制代码
  1. useContext
复制代码
的基本使用。

  1. forwardRef
复制代码
  1. useImperativeHandle
复制代码
的基本使用

  1. forwardRef
复制代码
  1. useImperativeHandle
复制代码
,它们通常一起使用,以便在父组件中暴露子组件的特定方法或属性。
  1. forwardRef
复制代码
,它允许你将父组件的
  1. ref
复制代码
转发到子组件中的某个 DOM 节点或其他 React 组件。这样,父组件就可以访问子组件的引用,并直接操作它。
  1. useImperativeHandle
复制代码
是一个自定义 Hook,它允许你自定义通过
  1. forwardRef
复制代码
暴露给父组件的
  1. ref
复制代码
值。你可以指定哪些
  1. 方法
复制代码
  1. 属性
复制代码
被暴露,而不是直接暴露整个 DOM 节点或组件实例。
下面是一个简单的例子
  1. import React, { forwardRef, useImperativeHandle, useRef } from 'react';

  2. const ChildComponent = forwardRef((props, ref) => {
  3.   const inputRef = useRef(null);

  4.   useImperativeHandle(ref, () => ({
  5.     focus: () => {
  6.       inputRef.current.focus();
  7.     },
  8.   }));

  9.   return <input ref={inputRef} {...props} />;
  10. });

  11. const ParentComponent = () => {
  12.   const childRef = useRef(null);

  13.   const handleClick = () => {
  14.     childRef.current.focus();
  15.   };

  16.   return (
  17.     <div>
  18.       <ChildComponent ref={childRef} />
  19.       <button onClick={handleClick}>Focus Child Input</button>
  20.     </div>
  21.   );
  22. };

  23. export default ParentComponent;
复制代码
使用forwardRef和useImperativeHanle封装全局Toast

封装组件
  1. import React, { createRef, forwardRef, useImperativeHandle } from 'react';
  2. import { Button, message } from 'antd';

  3. const Toast = forwardRef((props, ref) => {
  4.   const [messageApi, contextHolder] = message.useMessage();

  5.   useImperativeHandle(ref, () => ({
  6.     show: (msg: string) => {
  7.       messageApi.info(msg);
  8.     }
  9.   }));

  10.   return <>
  11.     {contextHolder}
  12.   </>
  13. })

  14. const ToastRef = createRef<{ show: (msg: string) => {} }>();

  15. export const ToastContain = () => {
  16.   return <Toast ref={ToastRef} />
  17. }

  18. export const showToast = (msg: string) => {
  19.   if (ToastRef.current) {
  20.     ToastRef.current.show(msg)
  21.   }
  22. };
复制代码
在入口中引入
  1. import React from 'react';
  2. import ReactDOM from 'react-dom/client';
  3. import './index.css';
  4. import App from './App';
  5. import router from '@/router/index'
  6. import reportWebVitals from './reportWebVitals';
  7. import { RouterProvider } from 'react-router-dom';
  8. import ErrorBoundary from './ErrorBoundary';
  9. import { ToastContain } from './components/Toast';

  10. const root = ReactDOM.createRoot(
  11.   document.getElementById('root') as HTMLElement
  12. );
  13. root.render(
  14.   <React.StrictMode>
  15.       <ToastContain />
  16.       <RouterProvider router={router} fallbackElement={<div>准备中</div>} />
  17.   </React.StrictMode>
  18. );
  19. reportWebVitals();
复制代码
然后就可以在全局中使用
  1. showToast
复制代码
方法了
  1. import React from 'react';
  2. import { showToast } from '../../../components/Toast';

  3. export default function Index() {
  4.   return <>
  5.     <div
  6.       onClick={() => {
  7.         showToast('sadasds')
  8.       }}
  9.     >
  10.        提示弹窗
  11.     </div>
  12.   </>
  13. }
复制代码
useContext的基本使用
  1. useContext
复制代码
用于访问组件树中某个层级上定义的
  1. Context
复制代码
  1. Context
复制代码
提供了一种在组件之间共享值的方式,而不必通过组件树的每个层级显式传递
  1. props
复制代码


  • 创建 Context
首先,你需要创建一个
  1. Context
复制代码
对象。这可以通过调用
  1. React.createContext
复制代码
来完成。你还可以为默认值提供一个参数,如果
  1. Context
复制代码
  1. Provider
复制代码
没有在组件树中找到,将使用这个默认值。
  1. import React from 'react';

  2. const MyContext = React.createContext('defaultValue');
复制代码

  • 提供 Context
你需要在组件树中的某个地方提供这个
  1. Context
复制代码
。这通常在组件的顶层完成,通过使用
  1. MyContext.Provider
复制代码
组件,并传递一个
  1. value
复制代码
prop
  1. import React from 'react';
  2. import MyComponent from './MyComponent';
  3. import { MyContext } from './MyContext';

  4. function App() {
  5.   return (
  6.     <MyContext.Provider value="Hello from Context">
  7.       <MyComponent />
  8.     </MyContext.Provider>
  9.   );
  10. }

  11. export default App;
复制代码

  • 使用
    1. useContext
    复制代码

在需要访问
  1. Context
复制代码
的组件中,你可以使用
  1. useContext
复制代码
Hook 来获取
  1. Context
复制代码
的当前值
  1. import React, { useContext } from 'react';
  2. import { MyContext } from './MyContext';

  3. function MyComponent() {
  4.   const contextValue = useContext(MyContext);

  5.   return <p>Context value: {contextValue}</p>;
  6. }

  7. export default MyComponent;
复制代码
使用useContext来封装全局Toast

封装组件
  1. import React, { createContext, useCallback, useContext, useState } from 'react';
  2. import { Button, message } from 'antd';

  3. const ToastContext = createContext<any>(null);

  4. export const ToastProvider = ({ children }: any) => {
  5.   const [messageApi, contextHolder] = message.useMessage();

  6.   const show = useCallback((msg: string) => {
  7.     messageApi.info(msg);
  8.   }, [messageApi]);

  9.   return (
  10.     <ToastContext.Provider value={{ show }}>
  11.       {children}
  12.       {contextHolder}
  13.     </ToastContext.Provider>
  14.   );
  15. };

  16. export const useToast = () => {
  17.   const context = useContext(ToastContext);
  18.   return context;
  19. };
复制代码
在入口处使用
  1. import React from 'react';
  2. import ReactDOM from 'react-dom/client';
  3. import './index.css';
  4. import App from './App';
  5. import router from '@/router/index'
  6. import reportWebVitals from './reportWebVitals';
  7. import { RouterProvider } from 'react-router-dom';
  8. import ErrorBoundary from './ErrorBoundary';
  9. import { ToastProvider } from './components/ToastOne';

  10. const root = ReactDOM.createRoot(
  11.   document.getElementById('root') as HTMLElement
  12. );
  13. root.render(
  14.   <React.StrictMode>
  15.     <ToastProvider>
  16.       <RouterProvider router={router} fallbackElement={<div>准备中</div>} />
  17.     </ToastProvider>
  18.   </React.StrictMode>
  19. );
复制代码
然后就可以通过
  1. useToast
复制代码
在全局中使用了
  1. import React from 'react';
  2. import { useToast } from '../../../components/ToastOne';

  3. export default function Index() {
  4.   const { show } = useToast()

  5.   return <>
  6.     <div
  7.       onClick={() => {
  8.         show('guiyu')
  9.       }}
  10.     >
  11.       点击提示
  12.     </div>
  13.   </>
  14. }
复制代码
结尾

以上就是基于React编写一个全局Toast的示例代码的详细内容,更多关于React编写全局Toast的资料请关注脚本之家其它相关文章!

来源:https://www.jb51.net/javascript/3209149mz.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具