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

mrp*_*ett 5 javascript alert user-experience reactjs

我希望让我的alert()用户更加友好。在触发警报之前,我有 3 个组件可以组合在一起。

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

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

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);
      });
  }
}
Run Code Online (Sandbox Code Playgroud)

但我想使用上面的警报<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')
);
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用alert()但这只是给了我标准的弹出窗口[object object]

任何想法如何让所有这 3 个文件与每个文件交谈以在满足条件时发出警报 getData()

这是我的 Alert 组件……我想保持原样

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;
Run Code Online (Sandbox Code Playgroud)

Ani*_*ony 5

您可以使用有问题的 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>
Run Code Online (Sandbox Code Playgroud)

您可以更改 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);
      });
  }
}

Run Code Online (Sandbox Code Playgroud)