当前位置: 代码网 > it编程>编程语言>Javascript > 基于React编写一个全局Toast的示例代码

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

2024年05月26日 Javascript 我要评论
前言前些日子在做项目的时候,需要封装一个toast组件。我想起之前用过的库,只要在入口文件中引入就可以在全局中使用,还是很方便的,借这次机会也来实现一下。说起来也算是forwardref、useimp

前言

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

  • 第一种,使用forwardrefuseimperativehanle

一个是像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()都有提示。忘记什么库了。

文中就用antdmessage来模拟一下我们自己写的toast组件。

正文

我们先来了解一下forwardrefuseimperativehanleusecontext的基本使用。

forwardrefuseimperativehandle 的基本使用

forwardrefuseimperativehandle,它们通常一起使用,以便在父组件中暴露子组件的特定方法或属性。

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 [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用于访问组件树中某个层级上定义的 contextcontext 提供了一种在组件之间共享值的方式,而不必通过组件树的每个层级显式传递 props

  • 创建 context

首先,你需要创建一个 context 对象。这可以通过调用 react.createcontext 来完成。你还可以为默认值提供一个参数,如果 contextprovider 没有在组件树中找到,将使用这个默认值。

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>
  </>
}

结尾

以上就是基于react编写一个全局toast的示例代码的详细内容,更多关于react编写全局toast的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com