我正在使用 Next.js 和react-dates构建一个应用程序。
我有两个组件DateRangePicker组件和DayPickerRangeController组件。
当窗口宽度大于 1180px 时,我想要渲染DateRangePicker ,如果尺寸小于此尺寸,我想要渲染DayPickerRangeController。
以下是代码:
windowSize > 1180 ? <DateRangePicker startDatePlaceholderText="Start" startDate={startDate} startDateId="startDate" onDatesChange={handleOnDateChange} endDate={endDate} endDateId="endDate" focusedInput={focus} transitionDuration={0} onFocusChange={(focusedInput) => { if (!focusedInput) { setFocus("startDate") } else { setFocus(focusedInput) } }} /> : <DayPickerRangeController isOutsideRange={day => isInclusivelyBeforeDay(day, moment().add(-1, 'days'))} startDate={startDate} onDatesChange={handleOnDateChange} endDate={endDate} focusedInput={focus} onFocusChange={(focusedInput) => { if (!focusedInput) { setFocus("startDate") } else { setFocus(focusedInput) } }} /> }
我通常使用带有窗口对象的 react hook 来检测窗口屏幕宽度,像这样
但是我发现这种方式在ssr的时候不可用,因为ssr渲染没有window对象。
有没有其他方法可以让我无论使用 ssr 都可以安全地获取窗口大小?
您可以通过添加以下代码来避免在 ssr 中调用检测函数:
// make sure your function is being called in client side only if (typeof window !== 'undefined') { // detect window screen width function }
来自您的链接的完整示例:
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 so server and client renders match // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/ const [windowSize, setWindowSize] = useState({ width: undefined, height: undefined, }); useEffect(() => { // only execute all the code below in 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 right away so state gets updated with initial window size handleResize(); // Remove event listener on cleanup return () => window.removeEventListener("resize", handleResize); }, []); // Empty array ensures that effect is only run on mount return windowSize; }
注意:根据 Sergey Dubovik 的评论更新,我们不需要验证窗口,因为 useEffect 在客户端运行