【问题标题】:Why is redux-sessionstorage not updating my node's attributes when restoring state?为什么 redux-sessionstorage 在恢复状态时不更新节点的属性?
【发布时间】:2019-03-14 15:21:14
【问题描述】:

我使用 redux-sessionstorage 将我的应用程序状态的子集存储到会话存储中。该状态的一部分表示 UI 中的某些面板是展开还是折叠(可见或隐藏)。

我有一个示例应用程序完全复制了这个:https://github.com/shawninder/sessionstorage-bug

有关完整的复制步骤,请参阅自述文件。

还在线托管here(给它一点时间解冻)

问题发生在我重新加载页面时。 redux-sessionstorage 正确地从 sessionStorage 恢复之前的状态并触发渲染,但我用来进行隐藏和显示的样式属性没有更新。

换句话说,这是按预期工作的:

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

我可以在页面加载时看到 showNotice: false,但是当 redux-sessionstorage 恢复保存状态时,它会立即被 showNotice: true 替换。

但以下不起作用:

<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 并显示&lt;div&gt;

为什么 redux-sessionstorage 没有更新这里的style 属性,人们一般是怎么处理的?

【问题讨论】:

  • 看看这里.. github.com/facebook/react/issues/11128 似乎服务器和客户端之间的反应版本差异?
  • 运行客户端和服务器端的代码相同,所以我看不出版本不匹配。我在其他地方看到了很多关于这个问题的信息,但是我无法将其他解决方案应用于我的案例,因为我没有进行调度,redux-sessionstorage 是......我希望添加 session-storage 标签在这里可以帮助我找到其他有相同特定问题的人...
  • @Shawn 我编辑了我的答案,更好地解释了代码失败的原因。

标签: javascript reactjs redux session-storage


【解决方案1】:

@lecstor 指出了有关此问题的正确线索。

这与服务器端渲染(SSR)有关。 Dan Abramov 在 comment 中描述的解决方法解决了这个问题。

您正在将 Next.js 用于 SSR。在dev 模式下运行项目时,在按 Toggle 为 true 并重新加载后,您可以在 Chrome 控制台上看到以下错误消息:

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

由于 Next 对客户端保存的状态一无所知,所以它总是返回 app.showNoticefalse。您还可以在 Chrome 网络选项卡上查看 GET localhost 返回的内容。

显然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>
    )
  }  
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 2016-06-11
    • 2017-01-25
    • 2019-09-24
    • 2018-01-25
    相关资源
    最近更新 更多