React无依赖的通知

There is a time (hopefully early on in the project) were the dev team must ditch the console.logs and inconsistent error labels and define a unified way to show notifications to users.

有一段时间(希望在项目的早期)开发团队必须放弃console.logs和不一致的错误标签,并定义统一的方式向用户显示通知。

Let’s build a hyper lightweight notification system that has no dependencies other than the standard react libraries and doesn’t need a state manager. Using a state manager will definitely improve the features we can add to the system, but let’s save that for a future post.

让我们构建一个超轻量级的通知系统,该系统除了标准的react库之外没有其他依赖项,并且不需要状态管理器。 使用状态管理器肯定会改善我们可以添加到系统中的功能,但让我们将其保存起来以备将来之用。

A functional demo can be found on Github: https://github.com/agustincastro/react-notifications

可以在Github上找到功能演示: https : //github.com/agustincastro/react-notifications

As the previous image shows I’ll use the popup’esque style of notifications sometimes called Snackbars. Everything about the style I presented can be easily changed, I just aim to present the approach.

如上图所示,我将使用弹出式通知样式,有时也称为Snackbars。 我介绍的样式的所有内容都可以轻松更改,我只是想介绍这种方法。

那将是什么方法? (And what will that approach be?)

  1. We will create a Snackbar component that will receive the message type(success, info, error, warning), the autohide timer, and the title and subtitle.

    我们将创建一个Snackbar组件,该组件将接收消息类型(成功,信息,错误,警告),自动隐藏计时器以及标题和副标题。
  2. A hook html tag with id=”snackbar-fixed-container” is placed in the main .html file, below our react “root” tag.

    一个具有id =“ snackbar-fixed-container”的hook html标记放置在主.html文件中,在我们的“ root”标记下方。

  3. Helper functions to display different kinds of messages are exported in a utility file. Those functions will add the Snackbar to the DOM in the html hook we defined in step 2.

    在实用程序文件中导出了用于显示各种消息的助手功能。 这些功能会将Snackbar添加到我们在步骤2中定义的html挂钩中的DOM中。
  4. We call those utility functions to display the snackbars from whatever component we fancy…. neat right?

    我们调用这些实用程序功能来显示我们喜欢的任何组件的小吃店……。 整洁吧?

够了,给我看代码 (Enough, show me the code)

Let’s begin adding our hook tab in the index.html of our public files.

让我们开始在公共文件的index.html中添加钩子标签。

<body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>


    <!-- Add this tags to hook our notifications -->
    <div class="snackbar-centered">
      <div id="snackbar-fixed-container" >
      </div>
    </div>


  </body>

We can create the Snackbar component, create a SnackBar.js file in your components folder of your react project and add the following content.

我们可以创建Snackbar组件,在react项目的components文件夹中创建SnackBar.js文件,并添加以下内容。

import React, { useState, useEffect } from "react";
import "../static/styles/snackbar.css";
import xIcon from "../static/images/x.svg";
import ReactDOM from 'react-dom';


/**
 * Neat Idea: When we integrate a state manager we can have a parent component that handles the display of notifications
 * instead of mounting them using reactDOM. Also we could use that container to render multiple notifications 
 * at once.
 */
export default function SnackBar(props) {


    const [closeTimeout, setCloseTimeout] = useState(null);


    useEffect(() => {
        beginCloseTimeout();
    }, []);


    const closeSnackBar = () => {
        clearTimeout(closeTimeout);
        ReactDOM.unmountComponentAtNode(document.getElementById('snackbar-fixed-container'));
    }


    const beginCloseTimeout = () => {
        if (props.timer) {
            const timeout = setTimeout(() => closeSnackBar(), props.timer);
            setCloseTimeout(timeout);
        }
    }


    return (
        <div className={`snackbar-container ${props.messageType}-container`}
            onMouseEnter={() => clearTimeout(closeTimeout)}
            onMouseLeave={() => beginCloseTimeout()}>
            <div>
                <div className="snackbar-info-container">
                    <div>
                        <div className={`snackbar-icon ${props.messageType}-snackbar-icon`}></div>
                    </div>
                    <div>
                        <h5 className="rubik-text">{props.title}</h5>
                        <h5 className="muted-rubik-text">  {props.message}</h5>
                    </div>
                </div>
                <div>
                    <img src={xIcon} onClick={() => closeSnackBar()} alt="close icon" id="close-snackbar-icon" />
                </div>
            </div>
        </div>
    );
}

This component will look horrible without styles, let’s create a css file for the component or add them directly if you use styled components. The images and fonts used can be found in the sample Github project.

如果没有样式,该组件将看起来很糟糕,让我们为该组件创建一个css文件,或者如果您使用样式组件,则直接添加它们。 可以在示例Github项目中找到使用的图像和字体。

.snackbar-centered {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}


.snackbar-container {
  width: 701px;
  box-shadow: 0 2px 8px 0 #1a273d40;
  border: solid 1px #e0e7ff;
  background-color: #ffffff;
  padding: 1rem 2rem;
  margin: 0 0.5rem;
}


.error-container {
  border-left: 4px solid red;
}


.info-container {
  border-left: 4px solid #2b89e9;
}


.success-container {
  border-left: 4px solid #4cd16d;
}


.warning-container {
  border-left: 4px solid #ffbc22;
}


.snackbar-container > div {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}


.snackbar-info-container {
  display: flex;
  align-items: center;
}


.snackbar-info-container > div > h5:nth-child(2) {
  margin-bottom: 0;
}


.snackbar-container > div > div:nth-child(1) {
  margin-right: 1rem;
}


.snackbar-icon {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-image: url(/static/media/alertCircle.3856fc8a.svg);
  background-repeat: no-repeat;
  background-position: center;
  margin-right: 1rem;
}


.error-snackbar-icon {
  background-color: red;
}


.info-snackbar-icon {
  background-color: #2b89e9;
}


.success-snackbar-icon {
  background-color: #4cd16d;
}


.warning-snackbar-icon {
  background-color: #ffbc22;
}


#close-snackbar-icon {
  height: 1.5rem;
  width: 1.5rem;
}


#snackbar-fixed-container {
  position: fixed;
  bottom: 4rem;
}


.rubik-text {
  font-family: "RubikMedium";
  font-size: 15px;
  font-weight: 500;
  color: #2e384d;
}


.muted-rubik-text {
  font-family: "RubikRegular";
  font-size: 15px;
  color: #2e384dce;
}


@media (max-width: 728px) {
  .snackbar-container {
    width: auto;
  }
}

Create a helper file in your utilities folder (if you have one) and add the following functions to trigger notifications.

在您的Utility文件夹(如果有)中创建一个助手文件,并添加以下功能来触发通知。

import ReactDOM from 'react-dom';
import React from "react";
import SnackBar from '../components/SnackBar';


const triggerSnackbar = (title, message, messageType) => {
    const validMessageTypes = ['error', 'info', 'warning', 'success'];
    if (!validMessageTypes.includes(messageType)) {
        throw Error("Invalid snackbar message type");
    }
    ReactDOM.render(
        <SnackBar messageType={messageType} timer={4000} title={title} message={message} />,
        document.getElementById('snackbar-fixed-container')
    );
}


export const showErrorMessage = (title, message) => {
    triggerSnackbar(title, message, 'error');
}


export const showInfoMessage = (title, message) => {
    triggerSnackbar(title, message, 'info');
}


export const showSuccessMessage = (title, message) => {
    triggerSnackbar(title, message, 'success');
}


export const showWarningMessage = (title, message) => {
    triggerSnackbar(title, message, 'warning');
}

Now the only thing missing is testing it out. Simply import the helper function for the notification you want and see how the snackbar is shown and suppressed after four seconds. If you hover over the Snackbar the timer will be paused and reseted with you leave.

现在唯一缺少的是对其进行测试。 只需导入所需通知的助手功能,并查看四秒钟后小吃栏的显示和隐藏方式。 如果将鼠标悬停在小吃栏上,则计时器将在您离开时暂停并重置。

import { showSuccessMessage, showErrorMessage } from '../../../helpers/exceptionUtils';


// HERE SHOULD BE YOUR COMPONENT CODE


try{
  showSuccessMessage("Nicely done", "You did very well");
}catch(e){
  showErrorMessage("Something exploded", "Better luck next time");
}

Voilá! There you have it, an extremely simple notification system for React that doesn’t depend on some heavy library. Now fine tune it and extend it to fit your project!!

瞧! 有了它,它是一个非常简单的React通知系统,它不依赖某些繁重的库。 现在微调并扩展它以适合您的项目!!

Future improvements could be adding stackable snackbars or modifying the api to receive a display position.

未来的改进可能是添加可堆叠的小吃吧或修改api以接收展示位置。

翻译自: https://medium.com/@agustin.castro.91/react-notifications-without-dependencies-801397777e85

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值