When submitting a form, I wish to show a small popup for 2.5 seconds if the server sends back a bad response.
The logic is fairly simple, however, I cannot figure out how to make this popup listen to a boolean somewhere in the state management(MobX in my case). I can get the content into the Popup just fine, however, the trigger is a button(and the content will show, if you click it) - But how do I make it listen to a boolean value somewhere?
Fairly simple class here:
import React from "react";
import { Popup, Button } from "semantic-ui-react";
import { inject } from "mobx-react";
const timeoutLength = 2500;
@inject("store")
export default class ErrorPopup extends React.Component {
state = {
isOpen: false
};
handleOpen = () => {
this.setState({
isOpen: true
});
this.timeout = setTimeout(() => {
this.setState({
isOpen: false
})
}, timeoutLength)
};
handleClose = () => {
this.setState({
isOpen: false
});
clearTimeout(this.timeout)
};
render () {
const errorContent = this.props.data;
if(errorContent){
return(
<Popup
trigger={<Button content='Open controlled popup' />}
content={errorContent}
on='click'
open={this.state.isOpen}
onClose={this.handleClose}
onOpen={this.handleOpen}
position='top center'
/>
)
}
}
}
However, the trigger value is a button which is rendered if this.props.data
is present. But that's not the behavior I wish; I simply want the popup to render(and thus trigger) if this.props.data
is there; alternatively, I can provide a true
value with props if need be.
But how do I make this component trigger without it being a hover/button?
How about passing in the isOpen prop? Then you could add some logic onto the componentWillReceiveProps hook:
import React from "react";
import { Popup, Button } from "semantic-ui-react";
import { inject } from "mobx-react";
const timeoutLength = 2500;
@inject("store")
export default class ErrorPopup extends React.Component {
constructor(props) {
super(props);
this.state = {
isOpen: false,
}
};
//This is where you trigger your methods
componentWillReceiveProps(nextProps){
if(true === nextProps.isOpen){
this.handleOpen();
} else {
this.handleClose();
}
}
handleOpen = () => {
this.setState({
isOpen: true
});
this.timeout = setTimeout(() => {
//No need to repeat yourself - use the existing method here
this.handleClose();
}, timeoutLength)
};
handleClose = () => {
this.setState({
isOpen: false
});
clearTimeout(this.timeout)
};
render () {
const errorContent = this.props.data;
if(errorContent){
return(
<Popup
trigger={<Button content='Open controlled popup' />}
content={errorContent}
on='click'
open={this.state.isOpen}
position='top center'
/>
)
}
}
}
Without a need of handling delay - you could simply pass in the isOpen prop and that would do the trick.
And here what it could look like in your parent component's render:
let isOpen = this.state.isOpen;
<ErrorPopup isOpen={isOpen}/>
Set this value to control the popup, ideally, this should be a part of your parent component's state. Having a stateful component as a parent is important to make the popup re-rendered