Set timeout on material UI drawer when open

Viewed 474

I would like to close the drawer after a specific time however I dont think material UI drawer has that kind of props. Is there a way to use transitionDuration to close the drawer or maybe add a setTimeout in my function ? When adding a timeout in my toggleDrawer function, it won't notice the timeout.

 <Drawer
              className="draww"
              anchor={anchor}
              open={state[anchor]}
              transitionDuration={2000}
              onClose={toggleDrawer(anchor, false)}
            >
              <div className="drawer-title">
                <Link to="/">
                  <h2>NOW NOW</h2>
                </Link>
              </div>

              <a className="cl" onClick={toggleDrawer(anchor, false)}>
                &times;
              </a>

              {/* {list(anchor)} */}
              <br />
              <div className="cart-drawer">
                <h4>YOUR SELECTION</h4>
                <div className="border-cart"></div>
                {cartItems.map((data) => (
                  <div className="row thiss">
                    <Link
                      to={{ pathname: `/product/${data._id}` }}
                      onClick={toggleDrawer(anchor, false)}
                    >
                      {data.product_image && (
                        <img
                          className="drawer-pic"
                          src={data.product_image.secure_url}
                          alt=""
                        />
                      )}
                    </Link>
                    <div className="col info-vart">
                      <Link
                        to={{ pathname: `/product/${data._id}` }}
                        onClick={toggleDrawer(anchor, false)}
                      >
                        <h2>{data.product_name.slice(0, 12)}</h2>
                        <h5>Ref:{data.product_details[1].TAILLE}</h5>
                        <button
                          onClick={() => removeProduct(data)}
                          className="remove"
                        >
                          DELETE
                        </button>
                      </Link>
                    </div>
                    <h3>€{data.product_price}</h3>
                  </div>
                ))}
                <div className="border-cart"></div>
                <div className="draw-down">
                  <div className="row ">
                    <p className="sub">TOTAL</p>
                    <p className="sub total">{formatNumber(total)}</p>
                  </div>
                  <div className="centerthis">
                    <button
                      type="button"
                      onClick={someFunc}
                      className="checkoutt"
                      role="link"
                    >
                      CHECKOUT
                    </button>
                    <PayPalScriptProvider
                      options={{
                        "client-id":
                          "",
                        currency: "EUR",
                      }}
                    >
                      <div
                        className="paypalll"
                        style={{
                          minWidth: "280px",
                          maxWidth: "280px",
                        }}
                      >
                        <PayPalButtons
                          style={{
                            layout: "horizontal",
                            height: 45,
                          }}
                          createOrder={(data, actions) => {
                            return actions.order.create({
                              purchase_units: [
                                {
                                  amount: {
                                    value: total,
                                  },
                                },
                              ],
                            });
                          }}
                        />
                      </div>
                    </PayPalScriptProvider>
                  </div>
                </div>
                <br />
              </div>
              <br />
            </Drawer>

Toggle drawer function

 const toggleDrawer = (anchor, open, data) => (event) => {
    if (
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return addProduct(data);
    }

    setState({ ...state, [anchor]: open });
  };
1 Answers

You can use a useEffect hook to close drawer after a timeout.

const allAnchors = ['left', 'right', 'top', 'bottom'];
for(let anchor of allAnchors) {
  useEffect(() => {
    if (state[anchor]) {
      setTimeout(() => {
        toggleDrawer(anchor, false)()
      }, 2000); // close after 2000ms
    }
  }, [state[anchor]]);
}

I saw you're using anchor variable, hinting that you might have multiple directions for drawer. If that's not the case, you can modify code and remove the for-loop entirely.

Here's a working example

const { useState, useEffect } = React;
const { Drawer, Button } = MaterialUI;

const App = (props) => {
  const [ state, setState ] = useState({});
  const allAnchors = [ 'left', 'right', 'top', 'bottom' ];
  
  for(let anchor of allAnchors) {
    useEffect(() => {
      if (state[anchor]) {
        setTimeout(() => {
          toggleDrawer(anchor, false)()
        }, 2000); // close after 2000ms
      }
    }, [state[anchor]]);
  }

   const toggleDrawer = (anchor, open, data) => (event) => {
    if (
      // check if event is not undefined
      event &&
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return addProduct(data);
    }
    
    if( typeof open === 'undefined') open = !state[anchor]

    setState(s => ({ ...s, [anchor]: open }));
  };

  return (
  <div>
  { allAnchors.map(anchor =>
    (
      <React.Fragment>
        <Button onClick={toggleDrawer(anchor)} >
          {anchor}
        </Button>
        <Drawer
          anchor={anchor}
          open={state[anchor]}
          onClose={toggleDrawer(anchor, false)}
        >
          This is Drawer
        </Drawer>
      </React.Fragment>
    ))
  }
  </div>
  )
}

ReactDOM.render(<App />, document.querySelector('#root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core@4.12.1/umd/material-ui.development.js"></script>
<div id="root" />

Related