Reactjs 无法基于在生产环境中运行的Gatsby应用程序中的URL参数更新JSX属性

Reactjs 无法基于在生产环境中运行的Gatsby应用程序中的URL参数更新JSX属性,reactjs,gatsby,Reactjs,Gatsby,在生产模式下,URL参数值不能用于呈现动态属性值。相同的URL参数值可用于呈现特定组件 我已经建立了一个回购协议,其中有一个最小的可复制示例 我们已经能够通过将参数值存储在state中来解决这个问题,但我不明白为什么需要这样做(特别是因为它呈现了正确的div) 相关代码(src/pages/index.js) constindexpage=({location})=>{ const params=新的URLSearchParams(location.search); const color=p

在生产模式下,URL参数值不能用于呈现动态属性值。相同的URL参数值可用于呈现特定组件

我已经建立了一个回购协议,其中有一个最小的可复制示例

我们已经能够通过将参数值存储在state中来解决这个问题,但我不明白为什么需要这样做(特别是因为它呈现了正确的div)

相关代码(src/pages/index.js)

constindexpage=({location})=>{
const params=新的URLSearchParams(location.search);
const color=params.get('color');
返回(
大家好
{颜色?

我应该是生产模式下的颜色{COLOR},即使在按CTRL+F5(硬刷新)后也是如此

: 未传递任何颜色。将?Color=blue添加到URL并按CTRL+F5以确保硬刷新

} 转到第2页 ) }

url参数
?color=blue
应该能够呈现适当的div并呈现适当的样式。div显示正确,但正确的样式不正确。

这个问题似乎是
过程如何为服务器应用程序工作

简短回答 您需要为颜色设置初始状态,然后在
useffect
hook中更新它:

const IndexPage = ({location}) => {
  const [color, setColor] = useState();
  useEffect(() => {
    setColor(new URLSearchParams(location.search).get('color'));
  }, location)
  return (
      <Layout>
        <SEO title="Home" />
        <h1>Hi people</h1>
        { color ?
          <p style={{color: color}}>
            I SHOULD BE THE COLOR {color} in production mode even after hitting CTRL+F5 (hard referesh)
          </p> :
          <p>
            No Color was passed. Add ?color=blue to URL and hit CTRL+F5 to ensure a hard refresh
          </p>
        }

        <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
          <Image />
        </div>
        <Link to="/page-2/">Go to page 2</Link>
      </Layout>
    )
  }
constindexpage=({location})=>{
const[color,setColor]=useState();
useffect(()=>{
setColor(新的URLSearchParams(location.search.get('color'));
},地点)
返回(
大家好
{颜色?

我应该是生产模式中的颜色{COLOR},即使在按CTRL+F5(硬引用)后也是如此

: 未传递任何颜色。将?Color=blue添加到URL并按CTRL+F5以确保硬刷新

} 转到第2页 ) }
长话短说 在为生产构建盖茨比应用程序时,它会为您呈现静态HTML。当您第一次在浏览器中加载页面时,它首先加载静态HTML,然后需要启动React和您的应用程序

在应用程序水合后,React将期望您的HTML内容与客户端呈现的React应用程序的第一次呈现相同。然而,在你的情况下,这不是真的

在React组件的第一次渲染中,段落元素上应该有一个
style
属性,该属性的值为URL查询参数中的颜色。在为页面构建静态HTML时,您的段落元素上不会有
style
属性,因为服务器上不存在查询参数

您可能想知道为什么文本内容在初始渲染时正确渲染查询参数中的颜色值。这是因为该方法可以修补文本内容中的差异,但无法修补HTML属性中的差异,这就是段落元素上的
style
属性所发生的情况

水合物
方法的React文档:

React期望服务器和客户端之间呈现的内容相同它可以修补文本内容中的差异,但您应该将不匹配视为错误并加以修复。在开发模式中,React警告水合过程中的不匹配。不能保证在不匹配的情况下修补属性差异。出于性能原因,这一点很重要,因为在大多数应用程序中,不匹配的情况很少发生,因此验证所有标记的成本将高得令人望而却步

由于初始HTML内容之间存在这种“不匹配”,因此应改为将
color
的默认值设置为状态属性,然后在组件首次装载时更新该值。这样,当您第一次在客户端加载应用程序时,如果存在
color
query参数,您将能够更新装载时的状态,以触发React组件的重新呈现

资源

感谢您的回答,让我们更好地了解引擎盖下实际发生的事情。很有帮助,没问题。感谢您花时间以问题为例建立回购协议。让你更容易理解发生了什么。嘿!花了大约一个小时来解决类似问题。这个答案非常有用。非常感谢。
const IndexPage = ({location}) => {
  const [color, setColor] = useState();
  useEffect(() => {
    setColor(new URLSearchParams(location.search).get('color'));
  }, location)
  return (
      <Layout>
        <SEO title="Home" />
        <h1>Hi people</h1>
        { color ?
          <p style={{color: color}}>
            I SHOULD BE THE COLOR {color} in production mode even after hitting CTRL+F5 (hard referesh)
          </p> :
          <p>
            No Color was passed. Add ?color=blue to URL and hit CTRL+F5 to ensure a hard refresh
          </p>
        }

        <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
          <Image />
        </div>
        <Link to="/page-2/">Go to page 2</Link>
      </Layout>
    )
  }