HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptTip

React hooks to handle window and environment events

Submitted by: @import:30-seconds-of-code··
0
Viewed 0 times
hookseventsandenvironmentreactwindowhandle

Problem

Handling window and environment events and changes in React components is definitely not a one-size-fits-all solution. However, React hooks can make it easier to manage these events and changes in a more organized way.
The useUnload hook is used to handle the beforeunload window event. This event is triggered when the user is about to close the window.
In order to implement this hook, you'll need to use the useRef() and useEffect() hooks. The useRef() hook is used to create a ref for the callback function, fn. The useEffect() hook is used to handle the 'beforeunload' event by using EventTarget.addEventListener(). Finally, EventTarget.removeEventListener() is used to perform cleanup after the component is unmounted.
To check if a client is online or offline, you can use the useOnline hook. This hook uses the Navigator.onLine web API to get the online status of the client.
Implementation-wise, you'll need to create a function, getOnLineStatus, that uses the Navigator.onLine web API to get the online status of the client. You'll also need to use the useState() hook to create an appropriate state variable, status, and setter.

Solution

const useUnload = fn => {
  const cb = React.useRef(fn);

  React.useEffect(() => {
    const onUnload = cb.current;
    window.addEventListener('beforeunload', onUnload);
    return () => {
      window.removeEventListener('beforeunload', onUnload);
    };
  }, [cb]);
};

const App = () => {
  useUnload(e => {
    e.preventDefault();
    const exit = confirm('Are you sure you want to leave?');
    if (exit) window.close();
  });
  return <div>Try closing the window.</div>;
};
ReactDOM.createRoot(document.getElementById('root')).render(
  <App />
);


In order to implement this hook, you'll need to use the useRef() and useEffect() hooks. The useRef() hook is used to create a ref for the callback function, fn. The useEffect() hook is used to handle the 'beforeunload' event by using EventTarget.addEventListener(). Finally, EventTarget.removeEventListener() is used to perform cleanup after the component is unmounted.
To check if a client is online or offline, you can use the useOnline hook. This hook uses the Navigator.onLine web API to get the online status of the client.
Implementation-wise, you'll need to create a function, getOnLineStatus, that uses the Navigator.onLine web API to get the online status of the client. You'll also need to use the useState() hook to create an appropriate state variable, status, and setter.
The useEffect() hook is used to add listeners for appropriate events, updating state, and cleanup those listeners when unmounting. Finally, the status state variable is returned.
Tracking the browser window's dimensions can be useful for responsive design. The useWindowSize hook can be used to track the dimensions of the browser window.
Using the useState() hook, you can initialize a state variable that will hold the window's dimensions. Initialize with both values set to undefined to avoid mismatch between server and client renders.

Code Snippets

const useUnload = fn => {
  const cb = React.useRef(fn);

  React.useEffect(() => {
    const onUnload = cb.current;
    window.addEventListener('beforeunload', onUnload);
    return () => {
      window.removeEventListener('beforeunload', onUnload);
    };
  }, [cb]);
};

const App = () => {
  useUnload(e => {
    e.preventDefault();
    const exit = confirm('Are you sure you want to leave?');
    if (exit) window.close();
  });
  return <div>Try closing the window.</div>;
};
ReactDOM.createRoot(document.getElementById('root')).render(
  <App />
);
const getOnLineStatus = () =>
  typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean'
    ? navigator.onLine
    : true;

const useOnline = () => {
  const [status, setStatus] = React.useState(getOnLineStatus());

  const setOnline = () => setStatus(true);
  const setOffline = () => setStatus(false);

  React.useEffect(() => {
    window.addEventListener('online', setOnline);
    window.addEventListener('offline', setOffline);

    return () => {
      window.removeEventListener('online', setOnline);
      window.removeEventListener('offline', setOffline);
    };
  }, []);

  return status;
};

const StatusIndicator = () => {
  const isOnline = useOnline();

  return <span>You are {isOnline ? 'online' : 'offline'}.</span>;
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <StatusIndicator />
);
const useWindowSize = () => {
  const [windowSize, setWindowSize] = React.useState({
    width: undefined,
    height: undefined,
  });

  React.useEffect(() => {
    const handleResize = () =>
      setWindowSize({ width: window.innerWidth, height: window.innerHeight });

    window.addEventListener('resize', handleResize);

    handleResize();

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  return windowSize;
};

const MyApp = () => {
  const { width, height } = useWindowSize();

  return (
    <p>
      Window size: ({width} x {height})
    </p>
  );
};

ReactDOM.createRoot(document.getElementById('root')).render(
  <MyApp />
);

Context

From 30-seconds-of-code: window-global-environment-ssr-hooks

Revisions (0)

No revisions yet.