Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Flash Message: How to make the message show without refreshing the page but refresh on 200

I want to show error (or success) message using FlashMessage while having my page reload at desired time

I'm using FlashMessage and my code looks like

render() {
  return (
    {this.state.error ? <FlashMessage duration={5000}><strong>{this.state.error.message}</strong></FlashMessage> : ''}
    //Some table here presenting data
    <Button variant="outline-info" type="submit" size="lg" block className="button-custom" onClick={this.handleSubmit.bind(this)}>
          Submit
        </Button>
  )}

for my stateful component, the error is loaded by

handleSubmit(event) {
let data = {
  name: this.state.name,
  unit_price: this.state.unit_price,
  length: this.state.length,
  time: this.state.selectedDate,
  instructor: this.state.instructor,
}
ApiService.postLesson(data)
.then(res => {
  this.setState({
    message: 'Success!'
  });
})
.catch(error => {
  this.setState({
    message: error,
    error: error,
  });
  console.log(error);
})

};

and my ApiService.postLesson is

const instance = axios.create({
  headers: {
    "Content-Type": "application/json",
    Authorization: 'Token ' + localStorage.getItem('token')
  },
});
export default {
  postLesson: data => 
    instance({
        'method': 'POST',
        'url': BACKEND_LESSONS_URL,
        'data': data
    }),
  // some other services

Now my problem is every time I click Submit, whether it's successful or not, it reloads the page. Because of that, I think my state is reloaded and the error is gone. If I add event.preventDefault() in handleSubmit, then I can see the message but then my content in the table would not be updated. What's a solution for this?

like image 275
JChao Avatar asked Nov 29 '20 16:11

JChao


1 Answers

Seems like you are on the right track and event.preventDefault() is really necessary for what you are trying to achieve.

So, you can refresh the page on success by calling location.reload():

handleSubmit(event) {
  event.preventDefault();
  let data = {
    name: this.state.name,
    unit_price: this.state.unit_price,
    length: this.state.length,
    time: this.state.selectedDate,
    instructor: this.state.instructor,
  }
  ApiService.postLesson(data)
    .then(res => {
      this.setState({
        message: 'Success!'
      });
      location.reload(); // refreshes the page
    })
    .catch(error => {
      this.setState({
        message: error,
        error: error,
      });
      console.log(error);
    })
}

It's not clear why do you need to refresh the entire page and bootstrap react app after successful postLesson() calls. However, there are potentially better options for your case:

  1. re-fetching the list of items displayed in table view
  2. or adding new lesson to the list on 200 response
handleSubmit(event) {
  event.preventDefault();
  let data = {
    name: this.state.name,
    unit_price: this.state.unit_price,
    length: this.state.length,
    time: this.state.selectedDate,
    instructor: this.state.instructor,
  }
  ApiService.postLesson(data)
    .then(res => {
      this.setState({
        message: 'Success!'
      });
      // 1. re-fetching list of items
      // ApiService.getLessons().then((lessons) => {this.setState({lessons})})

      // or 2. add newly posted lesson to the list 
      // this.setState({lessons: this.state.lessons.concat(data)})
    })
    .catch(error => {
      this.setState({
        message: error,
        error: error,
      });
      console.log(error);
    })
}

I hope this gives you a few ideas.

like image 86
Sergey Semashko Avatar answered Nov 08 '22 08:11

Sergey Semashko