0

I have a button in React that executes a function onClick. I want to get rid of the button, and instead programmatically execute the function if window width < 1000px.

A restriction is that I can not add a plugin.

Here's what the code looks like...

// Do I need useState, useEffect?
import React, { PureComponent } from "react";

class MainNav extends PureComponent {
state = {
  // Does something go here? What goes here and how do I use
  // state to execute the function?
  navIsCollapsed: false,
};

// this controls rendering of huge images
toggleShowImages() {
  this.setState({
    navIsCollapsed: !this.state.navIsCollapsed,
  });
}

// I want this to be executed by width < 1000
handleSideNavToggle = () => {
  this.toggleShowImages(); // controls if React renders components
  document.body.classList.toggle("side-nav-closed");
}

Here's render the button that's currently executing the function. I want width < 1000 to programmatically execute its function.

// window width < 1000 should execute this function
<div onClick={this.handleSideNavToggle}>Don't render huge images</div>

// here are the images the function conditionally renders
<should show images && 
  <div>Massive huge image</div>
  <div>Massive huge image</div>
  <div>Massive huge image</div>
>

I could use CSS media query to show or hide the massive images I don't want, but that's horrible use of React.

I've looked and tried to implement similar questions on SO that either invoke plugins, are out of date, or the use case is too different (for example, "re-render everything based on screen size"). I've also tried to React-ify vanilla javascript. This seems like it ought to be simple to do but I can't make it work.

Any React wizards out there who can answer with a clean, efficient solution?

2 Answers 2

6

Use the above method that Mathis Delaunay mentioned to get viewport/window width, then to get rid of that button. Just simply add a condition to whether render it or not and then watch on state changes to trigger the function. Here I use hooks to do it

import React, { useEffect, useState } from "react";
import ReactDOM from "react-dom";

function App() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    function handleResize() {
      setWidth(window.innerWidth);
    }
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, [width]);

  useEffect(() => {
    width < 600 && handleSideNavToggle();
  },[width]);

  function handleSideNavToggle() {
    console.log("toggle it");
  }

  return (
    <div className="App">
      {width > 600 && (
        <button onClick={() => handleSideNavToggle()}>
          Don't render huge images
        </button>
      )}
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Here is a working example. I set the width to be handled as 600 to make it easy to see.

https://codesandbox.io/s/react-hooks-counter-demo-w9wgv

Sign up to request clarification or add additional context in comments.

8 Comments

I don't want the button ever in the DOM at all. I want to replace the button with width < 1000 to render the function.
ok, then just hide that button when width < 1000, then use componenDidUpdate to watch on the width changes, if width < 1000, then execute the function you want.
I am not trying to hide the button. I want the React function to replace the button and execute the script when screen width < 1000. I want to delete the button entirely.
Ok, let me clarify your question, when window width < 1000, you want to remove the button and trigger this.handleSideNavToggle function automatically without have to be clicked? is that correct?
|
0

Try looking at this answer, i think it is what your are searching for :

Get viewport/window height in ReactJS

You just need to check in the updateWindowDimension if the window.innerWidth is under 1000, if so, change the css button property to display : none; or visibility: hidden;.

1 Comment

I've tried to implement that but although it delivers the width to the state, I'm too new to React to see where and how to call my function, and also everywhere I saw this answer it looked like the bind method was out of date. I need an answer with all the pieces.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.