乐闻世界logo
搜索文章和话题

How to detect window size in next js ssr using react hook

2个答案

1
2

In Next.js's Server-Side Rendering (SSR) environment, the absence of the browser window object prevents direct access to the window dimensions via React Hooks. However, you can obtain the window dimensions in the client-side (browser) environment by using React Hooks and set the state to make it available for components.

Here is how to retrieve the window dimensions using the React Hooks useState and useEffect:

jsx
import React, { useState, useEffect } from 'react'; const useWindowSize = () => { // Initialize state as undefined because the window dimensions cannot be determined during server-side rendering const [windowSize, setWindowSize] = useState({ width: undefined, height: undefined, }); useEffect(() => { // This code runs only in the client-side environment if (typeof window !== 'undefined') { // Function to handle window resize events const handleResize = () => { setWindowSize({ width: window.innerWidth, height: window.innerHeight, }); }; // Listen for window resize events window.addEventListener('resize', handleResize); // Immediately invoke to get the initial window dimensions handleResize(); // Cleanup function to remove the event listener when the component unmounts return () => window.removeEventListener('resize', handleResize); } }, []); // Empty array ensures the effect runs only when the component mounts and unmounts return windowSize; }; // Your component const MyComponent = () => { const { width, height } = useWindowSize(); return ( <div> {width && height ? ( <p>Window dimensions: width {width} px, height {height} px</p> ) : ( <p>Loading window dimensions...</p> )} </div> ); }; export default MyComponent;

In the above code, we define a custom Hook useWindowSize that returns the current window dimensions. During server-side rendering, the windowSize state is initialized to undefined because there is no window object. After the component is mounted to the DOM (in the client-side environment), useEffect is invoked, allowing us to safely access the window object to set the window dimensions. When the window dimensions change, the handleResize function updates the windowSize state.

Finally, in our component MyComponent, we use useWindowSize to retrieve and display the window dimensions. If the window dimensions are not yet determined (i.e., during server-side rendering), it may display a loading indicator or some placeholder content.

2024年6月29日 12:07 回复

To prevent the detection function from being called during SSR, add the following code:

javascript
if (typeof window !== 'undefined') { // Function to detect window screen width }

Here's a complete example from your link:

javascript
import { useState, useEffect } from 'react'; // Usage function App() { const size = useWindowSize(); return ( <div> {size.width}px / {size.height}px </div> ); } // Hook function useWindowSize() { // Initialize state with undefined width/height to match server and client renders // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/ const [windowSize, setWindowSize] = useState({ width: undefined, height: undefined, }); useEffect(() => { // Execute the code below only on the client side // Handler to call on window resize function handleResize() { // Set window width/height to state setWindowSize({ width: window.innerWidth, height: window.innerHeight, }); } // Add event listener window.addEventListener("resize", handleResize); // Call handler immediately to update state with initial window size handleResize(); // Remove event listener on cleanup return () => window.removeEventListener("resize", handleResize); }, []); // Empty array ensures the effect runs only on mount return windowSize; }

Note: Updated based on Sergey Dubovik's comment; validation of the window is unnecessary since useEffect runs on the client.

2024年6月29日 12:07 回复

你的答案