简体   繁体   English

Next.js 布局怪异行为; 反应条件渲染jsx不起作用

[英]Next.js layout weird behavior; React conditional rendering jsx not working

Let's say I have following simple set of files:假设我有以下一组简单的文件:

  • ./components/layout.js ./components/layout.js
import Navbar from './Navbar'
import Footer from './Footer'

import Header from '../components/Header'
import Head from 'next/head'
import Script from 'next/script'
import { app__mode } from '../settings/settings'

export default function Layout({
  children,
}) {
  return (
    <>
      <Head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <div className="__app__">
        {app__mode === "development" ? <Header /> : <><div>hoge.</div></>}
        <Navbar />
        <main>{children}</main>
        <Footer />
      </div>
    </>
  )
}
  • ./pages/_app.js ./pages/_app.js
import './../styles/styles.css';
import './../styles/styles.scss';

import Layout from '../components/layout'

export default function MyApp({ Component, pageProps }) {
  return <>
    <Layout>
      <Component {...pageProps} />
    </Layout>
  </>
}
  • ./settings/settings.js ./settings/settings.js
const app__mode = process.env.APP__MODE === 'production' ? 'production' : 'development';
const app__url = process.env.APP__URL;

export { app__mode, app__url, }

The problem is, when I build then npx next start to start the server (with APP__MODE=production env variable on the shell), on the page it shows the <Header /> component while it actually shouldn't, because I'm clearly stating {app__mode === "development"? <Header />: <><div>hoge.</div></>}问题是,当我构建然后 npx npx next start启动服务器(在 shell 上使用APP__MODE=production变量)时,它在页面上显示了<Header />组件,而它实际上不应该,因为我很清楚说明{app__mode === "development"? <Header />: <><div>hoge.</div></>} {app__mode === "development"? <Header />: <><div>hoge.</div></>} , and currently the app__mode value is production , it should be physically impossible, right?? {app__mode === "development"? <Header />: <><div>hoge.</div></>} ,而目前app__mode的值为production ,物理上应该是不可能的吧?? (I also confirmed that actually the app__mode value is production by placing a breakpoint nearby; ) (我还通过在附近放置断点来确认实际上app__mode值是production ;)

But one more weird point is, in the source code, I mean ctrl-U to show the html of the shown page, it doesn't contain the <Header /> html part, but instead it contains <div>hoge.</div> .但更奇怪的一点是,在源代码中,我的意思是 ctrl-U 显示显示页面的 html,它不包含<Header /> html 部分,而是包含<div>hoge.</div> What's happening???发生了什么???

Also, if I change {app__mode === "development"? <Header />: <><div>hoge.</div></>}另外,如果我改变{app__mode === "development"? <Header />: <><div>hoge.</div></>} {app__mode === "development"? <Header />: <><div>hoge.</div></>} to {app__mode === "development" && <Header />} instead, this time the whole page gets broken styled/layout. {app__mode === "development"? <Header />: <><div>hoge.</div></>}改为{app__mode === "development" && <Header />} ,这一次整个页面的样式/布局都被破坏了。

So my question:所以我的问题:

  1. Is this an intended behavior?这是预期的行为吗? If yes how/why?如果是,如何/为什么? If no give me related SO posts or links如果没有给我相关的 SO 帖子或链接
  2. So is it a bad idea to use conditional component rendering jsx on next.js layout pages?那么在 next.js 布局页面上使用条件组件渲染 jsx 是不是一个坏主意?
  3. Is this likely to be a some sort of caching issue?这可能是某种缓存问题吗? (But I ensured that 1. deleting.next each time 2. also tested on chrome browser with a fresh new profile...) (但我确保 1. 每次都删除.next 2. 还在 chrome 浏览器上使用全新的配置文件进行测试......)

Thanks.谢谢。

Thanks to the Shadi Amr 's comment I noticed that the whole set of problems is from the environmental variable part in the./settings/settings.js;感谢 Shadi Amr 的评论,我注意到整套问题来自 ./settings/settings.js 中的环境变量部分;

In the doc Basic Features: Environment Variables , the key parts it says are:在文档Basic Features: Environment Variables中,它说的关键部分是:

  • By default environment variables are only available in the Node.js environment;默认情况下,环境变量仅在 Node.js 环境中可用; expose a variable to the browser you have to prefix the variable with NEXT_PUBLIC_向浏览器公开一个变量,您必须在变量前面加上 NEXT_PUBLIC_
  • This inlining occurs at build time这种内联发生在构建时

So the weird problem is caused by 1. the env variables were working on node.js (so I saw it on the breakpoint) 2. but weren't working on browser (so the page layout/style broke) 3. and I thought I can pass env variables on the start too but actually on the build;所以奇怪的问题是由 1. env 变量在 node.js 上工作的(所以我在断点上看到它) 2. 但没有在浏览器上工作(所以页面布局/样式坏了) 3. 我想我可以在开始时也传递 env 变量,但实际上是在构建时传递;

So I changed the file as:所以我将文件更改为:

- const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development';
- const app__mode = process.env.APP__MODE === 'production' ? 'production' : 'development';
+ const app__mode = process.env.NEXT_PUBLIC_APP_MODE === 'production' ? 'production' : 'development';
+ const app__url = process.env.NEXT_PUBLIC_APP_URL;

export { app__mode, app__url, }

And also making sure to change the variables on the shell (or vscode tasks.json env values or whatever), re-build then re-start, it worked as expected.并确保更改 shell(或 vscode 任务。json 环境值或其他)上的变量,重新构建然后重新启动,它按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM