基于React编写一个全局Toast的示例代码
前言前些日子在做项目的时候,需要封装一个Toast组件。我想起之前用过的库,只要在入口文件中引入就可以在全局中使用,还是很方便的,借这次机会也来实现一下。说起来也算是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,它们通常一起使用,以便在父组件中暴露子组件的特定方法或属性。
forwardRef,它允许你将父组件的ref转发到子组件中的某个 DOM 节点或其他 React 组件。这样,父组件就可以访问子组件的引用,并直接操作它。
useImperativeHandle 是一个自定义 Hook,它允许你自定义通过 forwardRef 暴露给父组件的 ref 值。你可以指定哪些方法或属性被暴露,而不是直接暴露整个 DOM 节点或组件实例。
下面是一个简单的例子
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 = 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。
[*]创建 Context
首先,你需要创建一个 Context 对象。这可以通过调用 React.createContext 来完成。你还可以为默认值提供一个参数,如果 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 = message.useMessage();
const show = useCallback((msg: string) => {
messageApi.info(msg);
}, );
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>
</>
}
结尾
以上就是基于React编写一个全局Toast的示例代码的详细内容,更多关于React编写全局Toast的资料请关注脚本之家其它相关文章!
来源:https://www.jb51.net/javascript/3209149mz.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页:
[1]