BlueprintJS Toaster - How to set container without calling Toaster.create #5886
-
Environment
QuestionI have recently upgraded React and BlueprintJS to latest versions and after that I am having issues with the Toaster component of BlueprintJS. Initially we used to create a Toaster via the first method described in documentation i.e. Toaster.create(props, container) and with that we can supply the container element therefore I was able to show toasts in body (page level toast) and also inside a particular div(regional toast). With React 16 as mentioned in the Blueprint documentation we cannot use Toaster.create anymore "React 16 usage Toaster.create() will throw an error if invoked inside a component lifecycle method in React 16, as ReactDOM.render() will return null resulting in an inaccessible toaster instance. See the second bullet point on the React 16 release notes for more information." So now I am unable to assign a container to the toast. As per React 16 documentation, alternate to ReactDOM.render is ReactDOM.createPortal but looks like Blueprint is not yet using it. Do we have any alternatives to show toast in different containers on runtime? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
The other alternative mentioned in those release notes is to use refs. Instead of doing |
Beta Was this translation helpful? Give feedback.
-
Below is sample code using refs to create Toaster, can you please share how I can render the toasts into the "errorDiv"- import React, { Component } from 'react';
import { Toaster, Position, Button, Toast } from '@blueprintjs/core';
import '@blueprintjs/core/lib/css/blueprint.css';
class AppComponent extends Component {
setToasterRef = ref => {
this.toaster = ref;
}
onButtonClick = e => {
this.toaster.show({ message: 'this is new toast' });
}
render() {
return (
<div className="App">
<div style={{ width: '100%', height: '300px', backgroundColor: 'blue' }}>
<Button onClick={this.onButtonClick}>Toast</Button>
</div>
<div id="errorDiv" style={{ width: '100%', height: '200px', backgroundColor: 'red' }}>
</div>
<Toaster ref={this.setToasterRef} usePortal={false} position={Position.TOP} />
</div>
);
}
}
export default AppComponent; In actual scenario, I have a separate ToasterComponent which is a wrapper over the blueprint's toaster and is supplied the error message and container when a toast needs to be shown in any of the pages across my app. Below is the old way of supplying the container, in real scenario container was coming from the calling component which is already rendered in DOM - import React, { Component } from 'react';
import { Toaster, Position, Button, Toast } from '@blueprintjs/core';
class AppComponent extends Component {
constructor(props) {
super();
this.Toaster = null;
this.container = null;
}
componentDidMount() {
this.container = document.getElementById("errorDiv");
this.Toaster = {};
this.Toaster['toast1'] = Toaster.create({
toasts: [{
autoFocus: false,
canEscapeKeyClear: true,
position: Position.TOP,
container: this.container.id || this.container.tagName
}]
}, this.container);
}
onButtonClick = e => {
this.Toaster['toast1'].show({ timeout: 0, message: 'this is new toast' });
}
render() {
return (
<div className="App" >
<div style={{ width: '100%', height: '300px', backgroundColor: 'blue' }}>
<Button onClick={this.onButtonClick}>Toast</Button>
</div>
<div id="errorDiv" style={{ width: '100%', height: '200px', backgroundColor: 'red' }}>
</div>
</div>
);
}
}
export default AppComponent; |
Beta Was this translation helpful? Give feedback.
-
Hi @adidahiya, I suppose you are looking after this thread, let me know if you want any further details from my side or I am missing anything which Blueprint has provided. |
Beta Was this translation helpful? Give feedback.
The other alternative mentioned in those release notes is to use refs. Instead of doing
Toaster.create()
incomponentDidMount
, try doing it in a ref handler