React:使用具有自己样式的现有组件从多个组件触发自定义警报

React : Firing a custom alert from multiple components using an existing component having its own styles

我希望让我的 alert() 更加人性化。在触发警报之前,我有 3 个组件组合在一起。

我有一个表单(下拉和输入),在提交时会触发以下功能:

// src/components/input.js
<Btn onClick={() => getData(this.state.dropdown, this.state.value)}>Generate</Btn>

getData() 是下面的函数,它在一个单独的文件中 ../utils/debugger

// src/utils/debugger
async function getData(filter, captureName) {
  if (captureName === '') {
    alert(<Alert color='red' type='warning' message='this is an error' />);
  } else {
    axios({
      method: 'GET',
      url: `http://xxx/debugger/${filter}/${captureName}/logs`,
    })
      .then((res) => {
        if (res.data.length === 0) {
          alert(<Alert color='red' type='warning' message='this is an error' />);
        } else {
          alert(<Alert color='green' type='success' message='this is an error' />);
          console.log(res.data);
          data = res.data;
        }

        return res.data;
      })
      .catch((err) => {
        console.log(err);
      });
  }
}

但我想使用上面的警报在以下文件中显示我的 <Alert /> 组件:

// src/App.js
ReactDOM.render(
  <React.StrictMode>
    <script src='http://localhost:8097'></script>
    <div className='flex flex-col min-h-screen'>
      <header>
        <nav className='bg-gray-800'>
          <div className='mx-auto px-8'>
            <div className='flex items-center justify-between h-20'>
              <div>
                <span className='text-white font-bold'>Easy Debugger UI</span>
              </div>

              <div className=''>
                <Input /> // ../src/components/input.js
              </div>
            </div>
          </div>
        </nav>
      </header>

      <div className='container mx-auto'>
        <div className='my-2'>
          <Alert color='red' type='warning' message='waaaah' /> // display my alert here.
        </div>
        <main>
          <App />
        </main>
      </div>
      <footer className='mt-10'></footer>
    </div>
  </React.StrictMode>,
  document.getElementById('root')
);

我曾尝试使用 alert() 但这只给了我带有 [object object]

的标准弹出窗口

关于如何让所有这 3 个文件与每个文件对话以在 getData()

中满足条件时触发警报的任何想法

这是我的警报组件...我想保持原样

import React from 'react';

export const Alert = ({ color, type, message }) => {
  const [showAlert, setShowAlert] = React.useState(true);

  function AlertType(props) {
    const alertType = props.alertType;

    if (alertType === 'success') {
      return (
        <span role='img' className='text-3xl'>
          
        </span>
      );
    }

    if (alertType === 'warning') {
      return (
        <span role='img' className='text-3xl'>
          
        </span>
      );
    }
  }

  return (
    <>
      {showAlert ? (
        <div
          className={
            'text-white px-6 py-4 border-0 rounded relative mb-4 bg-' + color + '-500 flex items-center'
          }>
          <span className='text-xl inline-block mr-5 align-middle'>
            <AlertType alertType={type} />
          </span>
          <span className='inline-block align-middle mr-8'>
            <b className='uppercase'>{type}! </b>
            <span className='capitalize'>{message}</span>
          </span>
          <button
            className='absolute bg-transparent text-2xl font-semibold leading-none right-0 top-0 mt-4 mr-6 outline-none focus:outline-none'
            onClick={() => setShowAlert(false)}>
            <span>×</span>
          </button>
        </div>
      ) : null}
    </>
  );
};

export default Alert;

您可以使用有问题的警报组件,使用 react-universal-flash 进行少量修改,如下所示

只需将其用作 Flasher 组件的子组件

export const Alert = ({ content, type, deleteFlash}) => {
  const {color,inpType} = type;

  function AlertType(props) {
    const alertType = props.alertType;

    if (alertType === 'success') {
      return (
        <span role='img' className='text-3xl'>
          
        </span>
      );
    }

    if (alertType === 'warning') {
      return (
        <span role='img' className='text-3xl'>
          
        </span>
      );
    }
  }

  return (
        <div
          className={
            'text-white px-6 py-4 border-0 rounded relative mb-4 bg-' + color + '-500 flex items-center'
          }>
          <span className='text-xl inline-block mr-5 align-middle'>
            <AlertType alertType={inpType} />
          </span>
          <span className='inline-block align-middle mr-8'>
            <b className='uppercase'>{inpType}! </b>
            <span className='capitalize'>{content}</span>
          </span>
          <button
            className='absolute bg-transparent text-2xl font-semibold leading-none right-0 top-0 mt-4 mr-6 outline-none focus:outline-none'
            onClick={deleteFlash}>
            <span>×</span>
          </button>
        </div>
  );
};

export default Alert;


//Import it and use it as child of Flasher from react-universal-flash


<Flasher>
<Alert>
</Flasher>

您可以更改 flasher 的位置属性以将其定位在页面中的任何位置,例如“top_left”、“top_right”等

在触发消息时,您可以导入 flash 并根据警报中的自定义类型传递参数

// src/utils/debugger
async function getData(filter, captureName) {
  if (captureName === '') {
flash("this is an error",6000,{color:"red":inpType:"warning"})
  } else {
    axios({
      method: 'GET',
      url: `http://xxx/debugger/${filter}/${captureName}/logs`,
    })
      .then((res) => {
        if (res.data.length === 0) {
flash("this is an error",6000,{color:"red":inpType:"warning"})
        } else {

flash("this is an error",6000,{color:"green":inpType:"success"})
          console.log(res.data);
          data = res.data;
        }

        return res.data;
      })
      .catch((err) => {
        console.log(err);
      });
  }
}

您不能将 React 组件传递给 alert()。 alert() 需要一个字符串。

您可以使用 react tostify 来显示警报!!

首先,安装它:

npm install --save react-toastify

在你的app.js中:

  import React from 'react';
  import { ToastContainer, toast } from 'react-toastify';

  import 'react-toastify/dist/ReactToastify.css';
  // minified version is also included
  // import 'react-toastify/dist/ReactToastify.min.css';

  function App(){
    const notify = () => toast("Wow so easy !");

    return (
      <div>
        <button onClick={notify}>Notify !</button>
        <ToastContainer />
      </div>
    );
  }

记得在您的应用程序树中渲染一次 ToastContainer。如果你不知道把它放在哪里,在应用程序根目录中呈现它是最好的选择。

之后,您可以在任何需要的地方导入和调用 toast 函数。

阅读更多内容here.