schiehll / react-alert

alerts for React
MIT License
607 stars 99 forks source link

withAlert is not working #133

Closed OrKoN closed 5 years ago

OrKoN commented 5 years ago

My code is like:

import React from 'react'
import { ContextProviderComponent } from './Context'
import { withAlert } from 'react-alert'
import AlertTemplate from 'react-alert-template-basic'

// optional cofiguration
const options = {
  position: 'bottom right',
  timeout: 3000,
  offset: '30px',
  transition: 'scale',
}

class Root extends React.Component {
  render() {
    return (
      <ContextProviderComponent>{this.props.children}</ContextProviderComponent>
    )
  }
}

const RealRoot = withAlert({
  template: AlertTemplate,
  ...options,
})(Root)

export default RealRoot

And I get an error:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `ForwardRef(WithAlert(Root))`.

I am not sure maybe I am doing something wrong but I cannot figure it out. Is it supposed to work like this? I appreciate any help!

My versions:

"react": "16.8.6",
"react-alert": "5.5.0"
besLisbeth commented 5 years ago

Hi, @OrKoN! I'm curious - did you wrap your component with AlertProvider like in the Usage section from the documentation? I'm not seeing it in your example above - unless it is hidden in './Context' file.

OrKoN commented 5 years ago

@besLisbeth yes, I was using that and I tried different combinations. It's stopped working after I added my own context. So probably I was doing something wrong. Anyway, I actually gave up and implemented my own logic for the use case I have on one page:

  // Component methods
  sendAlert(message, options) {
    const alert = {
      message,
      options,
    }
    this.setState(
      {
        alerts: [...this.state.alerts, alert],
      },
      () => {
        setTimeout(() => {
          this.closeAlert(alert)
        }, 2000)
      }
    )
  }

  closeAlert(alert) {
    this.setState({
      alerts: this.state.alerts.filter(a => a !== alert),
    })
  }
import Alert from 'react-alert-template-basic'

// render
<div className={styles.alerts}>
  {this.state.alerts.map((a, i) => {
    return (
      <Alert
        close={() => this.closeAlert(a)}
        key={`alert${i}`}
        message={a.message}
        options={a.options}
      />
    )
  })}
</div>
.alerts {
  position: fixed;
  bottom: 50px;
  right: 50px;
  z-index: 100;

  > * {
    margin-top: 10px;
  }
}

Maybe someone will find it useful if they hit the same problem as I had (again probably it's me not understanding contexts and providers properly and also using gatsby which adds a bit of magic on its own).