JS3
JS3

Reputation: 1829

How can I make the Snackbar work in a class component?

These are my codes for the snackbar and it wasn't working whenever I'll click the button. I wanted the snackbar to appear once I'll click the button "confirm". Almost all of the examples I have seen are in a functional component, so how can I make the Snackbar work as expected in a class component?

class name extends Component {
  constructor() {
    super();
    this.state = { orders: [], open: false };
  }

  handleOpen = () => this.setState({ open: true });

  handleClose = () => this.setState({ open: false });

  columns = [
    {
      name: "Confirm",
      options: {
        customBodyRender: (value, tableMeta) => {
          return (
            <FormControlLabel
              value={value}
              control={
                <Button>
                  confirm
                </Button>
              }
              onClick={(e) => {
                try {
                  //firestore codes
                  );
                } catch (err) {
                  console.log(err);
                }
                this.handleOpen();
              }}
            />
          );
        },
      },
    },

  ];

   //code for options

   //data fetching codes
  
  render() {
    const { open } = this.state;
    return this.state.orders ? (
      <div>
        //muidatatable codes
        <Snackbar
          anchorOrigin={{
            vertical: "bottom",
            horizontal: "left",
          }}
          open={open}
          onClose={this.handleClose}
          autoHideDuration={2000}
          // other Snackbar props
        >
          Order Confirmed
        </Snackbar>
      </div>
    ) : (
      <p>Loading...</p>
    );
  }

}

Upvotes: 1

Views: 2478

Answers (2)

Lakshya
Lakshya

Reputation: 743

Ignoring a few syntax errors, you should check if there are any orders by using the length and not just by mere existence of the array as you have initialized an empty array this.state.orders will always result in true. Instead use this.state.orders.length > 0 ? to check if there are any orders or not.

Snackbar's child(ren) should be wrapped in components and not just strings directly, for using string directly you can use message prop of Snackbar.

Also, it's a standard to write class's name starting with an upper-case letter.

Here's a working code: Material UI Snackbar using classes

import React, { Component } from "react";
import { FormControlLabel, Button, Snackbar } from "@material-ui/core";
import MuiAlert from "@material-ui/lab/Alert";

export default class Name extends Component {
  constructor() {
    super();
    this.state = { orders: [], open: false };
  }

  handleOpen = () => this.setState({ open: true });

  handleClose = () => this.setState({ open: false });

  handleClick = () => this.setState({ orders: [1], open: true });
  columns = [
    {
      name: "Confirm",
      options: {
        customBodyRender: (value, tableMeta) => {
          return (
            <FormControlLabel
              value={value}
              control={<Button>confirm</Button>}
              onClick={(e) => {
                try {
                  //firestore codes
                } catch (err) {
                  console.log(err);
                }
                this.handleOpen();
              }}
            />
          );
        }
      }
    }
  ];

  //code for options

  //data fetching codes

  render() {
    const { open } = this.state;
    return (
      <>
        <Button variant="outlined" onClick={this.handleClick}>
          Open snackbar
        </Button>
        {this.state.orders.length > 0 ? (
          <div>
            <Snackbar
              anchorOrigin={{
                vertical: "bottom",
                horizontal: "left"
              }}
              open={open}
              onClose={this.handleClose}
              autoHideDuration={2000}
              // other Snackbar props
            >
              {/* <span
                style={{
                  background: "#000",
                  color: "#fff",
                  padding: "20px 5px",
                  width: "100%",
                  borderRadius: "5px"
                }}
              >
                Order Confirmed
              </span> */}
              <MuiAlert
                onClose={this.handleClose}
                severity="success"
                elevation={6}
                variant="filled"
              >
                Success Message
              </MuiAlert>
            </Snackbar>
          </div>
        ) : (
          <p>loading...</p>
        )}
      </>
    );
  }
}

Upvotes: 1

Abhishek Vyas
Abhishek Vyas

Reputation: 734

The following changes are made to make it work:

  • Removed Order Confirmed and used message prop of Snackbar
  • Passed values to orders array in constructor
  • Passed true in open variable.

Below is the working code for snack bar.

import React, { Component } from "react";
import Snackbar from "@material-ui/core/Snackbar";

class SnackBarSof extends Component {
  constructor() {
    super();
    this.state = { orders: [1, 2], open: true };
  }

  handleOpen = () => this.setState({ open: true });

  handleClose = () => this.setState({ open: false });

  render() {
    console.log(this.state.orders);
    console.log(this.state);
    const { open } = this.state;
    return this.state.orders ? (
      <div>
        <Snackbar
          anchorOrigin={{
            vertical: "bottom",
            horizontal: "left",
          }}
          open={open}
          onClose={this.handleClose}
          message="order confirmed"
          autoHideDuration={2000}
        ></Snackbar>
      </div>
    ) : (
      <p>Loading...</p>
    );
  }
}

export default SnackBarSof;

Upvotes: 1

Related Questions