Toast does not show
Toast to show
Please provide code examples that repros and exact error messages
@llorca apologies for the delay.
The defined method
import { Position, Toaster } from '@blueprintjs/core'
export const appNotification = dismissAction => Toaster.create({
className: 'app-toaster',
position: Position.TOP,
onDismiss: () => dismissAction()
})
The component
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { appNotification } from './utils/notification'
import Header from './components/Header'
import Footer from './components/Footer'
import { clearNotification } from './actions/app'
class Layout extends Component {
constructor(props) {
super(props)
this.state = {
toaster: null
}
}
componentDidMount() {
this.setState = {
toaster: appNotification(this.props.actions.clearNotification)
}
}
componentWillReceiveProps(nextProps) {
const { toaster } = this.state
const { app: { notification } } = this.props
const { app: { notification: nextNotification } } = nextProps
if (notification !== nextNotification) {
toaster && toaster.show(nextNotification)
}
}
render() {
const { app } = this.props
return (
<div>
<Header app={app} />
<div>
{this.props.children}
</div>
<Footer />
</div>
)
}
}
const mapStateToProps = state => ({
app: state.app
})
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators({ clearNotification }, dispatch)
})
Layout.propTypes = {
children: PropTypes.any.isRequired,
app: PropTypes.object.isRequired,
actions: PropTypes.shape({
clearNotification: PropTypes.func
})
}
export default connect(mapStateToProps, mapDispatchToProps)(Layout)
appNotification is always null, o calling .show(message) on it breaks ...
cannot call method show on null
this.setState = { should be this.setState({, no?
^ @casoetan - yes, try this and let us know if it fixes your issue.
@casoetan there are a number of bugs in your code, including the setState assignment mentioned above. The most glaring is, of course, that you're not using the Toaster API correctly:
Toaster.create() returns a toaster _instance_ with a show method. It is this show method which accepts onDismiss, so you're passing that handler in the wrong place.
The expected usage is something like this:
instance using Toaster.create() (typically one instance per position).common/toaster.ts so any component can simply import it and profit 馃捀js
export const TopToaster = Toaster.create({ position: TOP, ... })
instance.show({ ...props, onDismiss }) to show a toast in that Toaster.// later, in response to user event:
TopToaster.show({ ...props, onDismiss: this.handleDismiss })
```
Hope this helps! Please refactor your code and let us know if you can get it working.
Oh it's also worth noting that calling Toaster.create inside a component lifecycle method can actually return null (and it _definitely_ returns null in React 16): https://reactjs.org/blog/2017/09/26/react-v16.0.html#breaking-changes (2nd bullet)
_Edit:_ All this to support my proposal of defining a Toaster at initialization time (i.e., import) instead of at render() or mount time.
@AlexLandau the set state was obviously from scratching my head for over 2 days trying to get what worked on React 15 to work on React 16.
@giladgray you are quite right. In React 16, this would always return null. #https://github.com/facebook/react/issues/10309#issuecomment-318433235.
The Toaster does not work with SSR as it depends on the dom, reason I'm instantiating in ComponentDidMount.
@AlexLandau the set state was obviously from scratching my head for over 2 days trying to get what worked on React 15 to work on React 16.
@giladgray you are quite right. In React 16, this would always return null. #https://github.com/facebook/react/issues/10309#issuecomment-318433235.
The Toaster does not work with SSR as it depends on the dom, reason I'm instantiating in ComponentDidMount.
Solved with https://github.com/palantir/blueprint/issues/1205
export const Toast = (typeof window !== 'undefined')
? Toaster.create({
className: 'my-toaster',
position: Position.BOTTOM_RIGHT
})
: null
I am using a DIC for the toaster, so it calls it whenever its used for the first time.
In this case its also returning null.
Most helpful comment
Oh it's also worth noting that calling
Toaster.createinside a component lifecycle method can actually returnnull(and it _definitely_ returnsnullin React 16): https://reactjs.org/blog/2017/09/26/react-v16.0.html#breaking-changes (2nd bullet)_Edit:_ All this to support my proposal of defining a Toaster at initialization time (i.e.,
import) instead of atrender()ormounttime.