2

I want the className should be added or removed automatically when the screen size changes.

I tried using media queries, but that didn't really work for me. In my stylesheet I have predefined classes for example:

.bold { font-weight: bold;}

and this classes cannot be added or removed using media queries.

1
  • 2
    Why do you want to do this? Have you considered using media queries? Please edit your question to add more detail. Commented Feb 7, 2018 at 17:18

3 Answers 3

14

Attach a resize event handler to window, then you can check the screen size and use that to update state. Then in render, you should check state to tell whether or not the new class should be added or removed:

componentDidMount() {
    window.addEventListener('resize', () => {
        this.setState({
            isMobile: window.innerWidth < 1200
        });
    }, false);
}

render() {
    const className = this.state.isMobile ? 'mobile' : '';
    return (
        <Component className={className} />
    )
}
Sign up to request clarification or add additional context in comments.

3 Comments

as an addition, if the component could potentially unmount you should also add a componentWillUnmount function to remove the listener otherwise it will keep erroring
I would recommend throttling the resize handler
This will be run while resizing your screen - what about to have this function to be run always not when resizing. Thanks
12

If you're looking to do this with hooks instead of classes, here is a simple example for this case:

const [isMobile, setIsMobile] = useState(window.innerWidth < 1200);

{/* Performs similarly to componentDidMount in classes */}
useEffect(() => {
    window.addEventListener("resize", () => {
        const ismobile = window.innerWidth < 1200;
        if (ismobile !== isMobile) setIsMobile(ismobile);
    }, false);
}, [isMobile]);

{/* There is no need for a render function with Hooks */}
return (
    <p className={`${isMobile ? "mobile-class" : "non-mobile-class"}`}>Your text here</p>
);

For a more in-depth explanation of the useEffect hook, check out the official React documentation here. Please note that you must be using React 16.8 or higher to take advantage of hooks.

6 Comments

Hi you can add a return statement in the useEffect to clean up, when it unmounts
@FaizHameed can you explain what you mean? I'm still rather new to React and I'd love to learn how to improve the code
Does this creates performance issues?
@AyushKumar it shouldn't, React hooks are designed to be efficient if used properly
@AaronMeese I am talking about memory leaks when you don't remove them, when the component unmounts.
|
1

the solution above is firing the event every time you resize, perhaps something like this would be a better option:

  const mediaQuery: string = "(min-width: 768px)";
  const mediaQueryMatch = window.matchMedia(mediaQuery);
  const [isMobile, setIsMobile] = useState(false);

  useEffect(() => {
    const handleClassByMediaQuery = (event: { matches: any }) => {
      const isMobile = event.matches;

      return setIsMobile(isMobile);
    };
    mediaQueryMatch.addEventListener("change", handleClassByMediaQuery);

    return () => {
      mediaQueryMatch.removeEventListener("change", handleClassByMediaQuery);
    };
  }, [isMobile, mediaQueryMatch]);

1 Comment

the solution above Which one? The other answers are not always "above". Sure, they are while you type your answer - but then they're sorted in the page once posted. Criteria are "Trending", "Highest score", "Date modified", "Date created". Your answer is placed in the page according to this parameter.

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.