Невозможно обновить атрибут JSX на основе параметра URL в приложении Gatsby, работающем в рабочей среде - PullRequest
2 голосов
/ 31 мая 2019

В рабочем режиме значение параметра URL нельзя использовать для отображения динамических значений атрибута. То же значение параметра URL можно использовать для визуализации определенного компонента.

Я настроил репо с минимальным воспроизводимым примером.

https://github.com/mikepuglisi/gatsby-dynamic-attribute-bug

Мы смогли обойти это, сохранив значения параметров в состоянии, но я не понимаю, почему это должно быть необходимо (особенно потому, что оно отображает правильный div).

Соответствующий код (src / pages / index.js)

const IndexPage = ({location}) => {
  const params = new URLSearchParams(location.search);
  const color = params.get('color');
  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 refresh)
          </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>
    )
  }

Параметр url ?color=blue должен отображать соответствующий div и отображать соответствующий стиль. Div показывает правильно, но правильный стиль не. Снимок экрана проблемы

1 Ответ

3 голосов
/ 01 июня 2019

Эта проблема, по-видимому, заключается в том, как процесс hydration работает для приложений React, отображаемых на сервере.

Короткий ответ

Вам необходимо установить начальное состояние для цвета, а затем обновить его с помощью useEffect 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>
    )
  }

Длинный ответ

При создании приложения Gatsby для производства оно выдает статический HTML-код, используя ReactDOMSever. При первой загрузке страницы в браузере он загружает статический HTML-код, а затем ему нужно загрузить React и hydrate ваше приложение.

После увлажнения вашего приложения React будет ожидать, что ваш HTML-контент будет идентичен тому, который был бы представлен при первом рендеринге отрисованного на стороне клиента приложения React. Однако в вашем случае это не так.

При первом рендеринге для вашего компонента React у вас должен быть атрибут style в вашем элементе абзаца со значением цвета, найденного в параметрах URL-запроса. При создании статического HTML-кода для страницы у вас не будет атрибута style в вашем элементе абзаца, поскольку параметры запроса не существуют на сервере.

Вам может быть интересно, почему текстовое содержимое правильно отображает значение цвета из параметров запроса при первоначальной визуализации. Это связано с тем, что метод hydrate может исправлять различия в текстовом содержимом, но он не может исправлять различия в ваших атрибутах HTML, как это происходит с вашим атрибутом style в элементе абзаца.

Из документов React для метода hydrate:

React ожидает, что отображаемый контент идентичен между сервером и клиентом. Может исправлять различия в текстовом содержимом , но вы должны рассматривать несоответствия как ошибки и исправлять их. В режиме разработки React предупреждает о несоответствиях во время гидратации. не гарантирует, что различия атрибутов будут исправлены в случае несоответствия . Это важно по соображениям производительности, поскольку в большинстве приложений несоответствия встречаются редко, и поэтому проверка всей разметки будет непомерно дорогой.

Из-за этого "несоответствия" между исходным содержимым HTML вместо этого следует установить значение по умолчанию для color в качестве свойства состояния, а затем обновить это значение при первом монтировании компонента. Таким образом, когда вы впервые загрузите приложение на клиенте и у вас будет присутствовать параметр запроса color, вы сможете обновить состояние при монтировании, чтобы запустить повторную визуализацию вашего компонента React.

Ресурсы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...