Рендеринг на стороне сервера с React со случайно сгенерированной строкой?

Я впервые пытаюсь выполнить рендеринг на стороне сервера в своем приложении React/Redux. Проблема, с которой я сталкиваюсь сейчас, заключается в том, что мне нужно, чтобы начальное состояние имело случайно сгенерированную строку, а затем передавало ее в качестве опоры моей главной App составная часть. Это, очевидно, вызывает проблему, потому что он генерирует разные строки для клиента и сервера. Могу ли я что-нибудь сделать, чтобы эта проблема не возникла?

Основная структура, чтобы помочь с пониманием:

App.js

import React from 'react';
import { connect } from 'react-redux';

const App = ({ randomStr }) => (
  <div> 
    <p>{randomStr}</p>
  </div>
);

const mapStateToProps = (state) => ({
  ...
});

const mapDispatchToProp = (dispatch) => ({
  ...
});

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

И мой редуктор:

reducer.js

import { generateString } from '../util';
import { NEW_STRING } from '../constants';

const stringReducer = (state = generateString(), action) => {
  switch (action.type) {
    case NEW_STRING:
      return generateString();

    default:
      return state;
  }
};

export default stringReducer;

Как видите, я получаю randomStr из моего магазина приставки и рендеринга, но он отличается в клиенте и сервере. Любая помощь будет оценена!

2 ответа

Решение

Когда вы генерируете хранилище и ваше начальное состояние на стороне сервера, клиент не должен делать то же самое и пытаться восстановить данные.

Вам нужно сгенерировать ваш магазин и ваше начальное состояние только один раз (на сервере) и передать его клиенту. Для этого вам нужно вставить его в начальный компонент, который вы будете рендерить.

Наиболее распространенным подходом является добавление <script> пометить и прикрепить состояние к вашему окну, например, в window.__initialState,

Например, если вы используете ReactDOM.renderToString на стороне сервера для визуализации вашего начального компонента под названием Html, вы можете:

const html = ReactDOM.renderToString(<Html initialState={initialState} />);

Тогда в вашем Html компонент, вы можете внедрить эти данные, чтобы клиент мог использовать их позже:

<script dangerouslySetInnerHTML={{ __html: `window.__initialState=${JSON.stringify(this.props.initialState)};` }}/>

После этого на стороне клиента вы можете использовать window.__initialState чтобы вернуть ваши данные, и вы получите те же данные на сервере и клиенте.

Давайте распространим информацию! React создал для этого крючок под названиемuseIdначиная с реакции 18. https://react.dev/reference/react/useId

Целью является создание случайных значений между рендерингом на стороне [сервера и клиента].

Другие вопросы по тегам