【问题标题】:conditional rendering of component in Next jsNext js中组件的条件渲染
【发布时间】:2021-02-13 05:38:02
【问题描述】:

我曾经通过写这样的东西来根据屏幕宽度渲染组件。

function App(props) {
    const [mobile, setMobile] = useState(() => window.innerWidth < 576 ? true : false)
    return (
        <div>
            {
                mobile ? <ComponentA /> : <ComponentB />
            }
        </div >
    );
}

但现在我正在使用 Next.js,由于 window.innerWidth 引用,这给了我几个错误。 我怎么能这样做? 提前致谢。

【问题讨论】:

  • 欢迎来到 S.O.错误信息是什么?
  • 可能会签出medium.com/frontend-digest/…
  • NextJS 是同构的(在服务器和客户端上运行)。 window 在服务器上未定义,因此您会看到一个错误。您需要进行检查,例如window &amp;&amp; window.innerWidth &lt; 576
  • window &amp;&amp; 仍然会抛出服务器端。 typeof 可用于检查变量是否已安全声明,例如typeof window !== 'undefined' &amp;&amp; window.innerWidth &lt; 576 ? true : false

标签: reactjs next.js


【解决方案1】:

您收到一个引用错误,因为您无法访问 useState 中的 window 对象。相反,您必须将 useState 中的初始值设置为undefinednull 并使用useEffect 其中window 可以被引用以调用setMobile(window.innerWidth &lt; 576 ? true : false)。最后,在您的渲染方法中,您可以检查是否使用setMobile 设置了mobile 状态(即,不是undefinednull)并使用定义的移动状态值(truefalse)有条件地呈现您的 ComponentA 或 ComponentB。此外,您需要在安装 App 组件时添加 window.addEventListener('resize', handleResize),并在卸载时删除它,您也可以在 useEffect 中执行此操作,因为这是您引用 window 的地方。否则,调整浏览器大小不会触发对mobile 状态的更新。这是一个工作示例:


import React, { useState, useEffect } from 'react'

function App() {
  const [mobile, setMobile] = useState(undefined)

  useEffect(() => {
    const updateMobile = () => {
      setMobile(window.innerWidth < 576 ? true : false)
    }

    updateMobile()
    window.addEventListener('resize', updateMobile)
    return () => {
      window.removeEventListener('resize', updateMobile)
    }
  }, [])

  return typeof mobile !== 'undefined' ? (
    mobile ? (
      <ComponentA />
    ) : (
      <ComponentB />
    )
  ) : null
}

【讨论】:

  • 哇!这太棒了。它工作正常。我整天都在尝试使用 useState、useEffect 和 process.browser,阅读有关服务器端的非窗口的信息。在第一次渲染中,我遇到了一个或另一个组件的无限循环错误。第一次渲染既不显示组件A,也不显示组件B。那是关键。非常感谢。
【解决方案2】:

假设您看到的内容类似于ReferenceError: window is not defined

ReferenceError 在引用不存在的变量时抛出。

发生这种情况是因为在 NextJS 中,组件通常最初使用 NodeJS 在服务器端呈现,然后才移交给客户端使用。此外,在 NodeJS 中,没有 window 这样的东西——因此,没有定义窗口

幸运的是,typeof 可以在这种情况下用于在尝试使用变量之前安全地检查变量(有关更多信息,请参阅 this SO answer)。

请参阅下面的实际示例。

const [mobile, setMobile] = useState(() => {
  if (typeof window === 'undefined') return false
  return window.innerWidth < 576
})

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 2017-11-22
    • 2016-12-16
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 2020-03-22
    相关资源
    最近更新 更多