Explain Codes LogoExplain Codes Logo

Rerender view on browser resize with React

javascript
debouncing
custom-hooks
event-listeners
Nikita BarsukovbyNikita BarsukovΒ·Oct 23, 2024
⚑TLDR

Rerender your React components on browser resize effectively by setting up a resize event listener and employing window dimensions for state updating using useState and useEffect hooks. Let's dive into the quick solution:

import { useState, useEffect } from 'react'; const useWindowSize = () => { const [size, setSize] = useState([window.innerWidth, window.innerHeight]); useEffect(() => { const resizeHandler = () => setSize([window.innerWidth, window.innerHeight]);//Changing dimensions? No problem! πŸ‘ window.addEventListener('resize', resizeHandler); return () => window.removeEventListener('resize', resizeHandler); }, []); return size; }; function MyResponsiveComponent() { const [width, height] = useWindowSize(); return <div>Width: {width}, Height: {height}</div>;//Responsive and snappy! πŸ’₯ }

This custom hook, useWindowSize, encapsulates the resize logic, allowing your component to concentrate on showcasing your constantly updated window dimensions.

Work smarter with debouncing

Enhance your performance by using debouncing. This technique helps limit the number of re-renders triggered by the resize event. Rather than reacting to every window tweak, do it the smart way:

import { useState, useEffect } from 'react'; import debounce from 'lodash.debounce'; const useWindowSize = () => { const [size, setSize] = useState([window.innerWidth, window.innerHeight]); useEffect(() => { const debouncedResizeHandler = debounce(() => { setSize([window.innerWidth, window.innerHeight]);//This resize isn't getting past me! πŸ•΅οΈβ€β™‚οΈ }, 100); window.addEventListener('resize', debouncedResizeHandler); return () => { debouncedResizeHandler.cancel(); window.removeEventListener('resize', debouncedResizeHandler); }; }, []); return size; };

Debouncing: fewer calls, less re-render chaos, more performance magic. πŸ’ƒ

Keep it DRY with custom hooks

Build a custom hook for window resizing for cleaner and more maintainable code. Let your hooks do the heavy lifting!

// useWindowSize.js import { useState, useEffect } from 'react'; export default function useWindowSize(){ // ...same as above... } // MyResponsiveComponent.js import useWindowSize from './useWindowSize'; function MyResponsiveComponent() { // ...use your custom hook... }

This structure abides by the DRY (Don't Repeat Yourself) principle and keeps your logic nicely organized.

Keep context intact with arrow functions

Leverage arrow functions to maintain the this context in event listeners, without the need to bind:

componentDidMount() { window.addEventListener('resize', this.handleResize); } handleResize = () => { // 'this' is correctly bound, no "undefined" surprises here! 🎁 };

Arrow functions: where this behaves and code becomes more readable. 🌈

React lifecycle methods for class components

For class components, use lifecycle methods to handle resizing events:

class MyResponsiveClassComponent extends React.Component { state = { width: window.innerWidth, height: window.innerHeight, }; componentDidMount() { window.addEventListener('resize', this.handleResize);//Ready to listen! 🎧 } componentWillUnmount() { window.removeEventListener('resize', this.handleResize);//Talk to the hand! πŸ–οΈ } handleResize = () => { this.setState({ width: window.innerWidth, height: window.innerHeight, }); }; render() { return <div>Width: {this.state.width}, Height: {this.state.height}</div>; } }

Not only are new event listeners set up, but inactive ones are discarded, ensuring memory cleanliness.

Tidy side effects with useEffect

The useEffect hook is handy to conduct side-effects and guarantee a neat and timely listener cleanup:

useEffect(() => { // ...set up resize listener... return () => { // Cleanup is the secret sauce! 🧹 window.removeEventListener('resize', resizeHandler); }; }, []);

Cleaning up global objects such as window helps prevent performance issues and memory leaks, keeping your app healthy.

Controlling re-render with state manipulation

Tighten the reins on your component re-rendering process by manipulating state. Call setState or use the forceUpdate method for a resize effect:

this.setState({ width: window.innerWidth }); // or this.forceUpdate();

This prompts the component to re-render with the latest window dimensions in real-time.

Retrieve window size data

Grab the window dimensions by accessing properties window.innerWidth and window.innerHeight directly:

const width = window.innerWidth; const height = window.innerHeight;

Realizing responsive designs becomes hassle-free with direct access to window size data.

Enhancements using CSS media queries

For more elegance, combine your JavaScript resize logic with CSS media queries. CSS and React can beautifully co-exist to give you the strongest responsive design.

Prioritize performance

Remember, resizing operation is crucial, but so is performanceβ€”optimize your resize event handling using techniques like debouncing or throttling.