Почему redux-sessionstorage не обновляет атрибуты моего узла при восстановлении состояния? - PullRequest
2 голосов
/ 14 марта 2019

Я использую redux-sessionstorage для хранения подмножества состояния моего приложения в хранилище сеансов.Часть этого состояния указывает, развернуты или свернуты определенные панели в пользовательском интерфейсе (видимые или скрытые).

У меня есть образец приложения, воспроизводящий именно это: https://github.com/shawninder/sessionstorage-bug

См. Файл readme для полногошаги воспроизведения.

Также размещено в Интернете здесь (дайте ему возможность разморозиться)

Проблема возникает, когда я перезагружаю страницу.redux-sessionstorage правильно восстанавливает предыдущее состояние из sessionstorage и запускает рендеринг, однако атрибут стиля, который я использую для скрытия и отображения, не обновляется.

Другими словами, это работает, как и ожидалось:

<p>showNotice: {props.app.showNotice ? 'true' : 'false'}</p>

Я вижу showNotice: false при загрузке страницы, но он сразу же заменяется на showNotice: true, когда redux-sessionstorage восстанавливает сохраненное состояние.

Но следующее не работает:

<div
  className='notice'
  style={{
    opacity: props.app.showNotice ? 1 : 0,
    transform: props.app.showNotice ? 'translateX(0)' : 'translateX(-100%)'
  }}
>
  Notice!
</div>

Страница загружается со скрытым уведомлением (как и ожидалось), но не отображается, когда redux-sessionstorage восстанавливает состояние.На самом деле, он не отображается, пока я дважды не нажму кнопку переключения, первый раз, чтобы установить showNotice обратно на false, а затем второй раз, чтобы установить его на true и показать <div>.

Почему redux-sessionstorage не обновляет здесь атрибут style, и как люди обычно справляются с этим?

1 Ответ

0 голосов
/ 21 марта 2019

@ lecstor указал на правую ветку об этой проблеме.

Это относится к рендерингу на стороне сервера (SSR). Обходной путь, описанный Даном Абрамовым в этом комментарии , решил проблему.

Вы используете Next.js для SSR. При запуске проекта в режиме dev вы можете увидеть следующее сообщение об ошибке на консоли Chrome после нажатия Toggle на true и перезагрузки:

Warning: Text content did not match. Server: "false" Client: "true"

Так как Next ничего не знает о сохраненном состоянии на стороне клиента, он всегда возвращает app.showNotice в false. Вы также можете проверить возвращенный контент для GET localhost на вкладке Chrome Network.

Очевидно, Next.js пытается объединить содержимое, возвращенное с сервера, и содержимое, отображаемое локально, но не может объединить стиль. По-видимому, это ожидаемое поведение в Next, а также в React 16 SSR, которое вы можете преодолеть, вызвав вторую render() или выполнив приведенную ниже реализацию.

class App extends Component {

  constructor(props) {
    super(props);
    this.state = { showNotice: false };
  }

  componentDidMount() {
    this.setState({ showNotice: this.props.app.showNotice });
  }

  componentWillReceiveProps(props) {
    this.setState({ showNotice: props.app.showNotice });
  }

  render() {
    return (
      <div>
        <p>showNotice: {this.state.showNotice ? 'true' : 'false'}</p>
        <button onClick={(event) => {
          this.props.dispatch({ type: 'App:toggleNotice' })
        }}>toggle</button>
        <div
          className='notice'
          style={{
            opacity: this.state.showNotice ? 1 : 0,
            transform: this.state.showNotice ? 'translateX(0)' : 'translateX(-100%)'
          }}
        >
          Notice!
        </div>
        <style jsx>{`
          .notice {
            width: 100px;
            transition-property: opacity, transform;
            transition-duration: 0.4s;
          }
        `}</style>
      </div>
    )
  }  
}
...