为什么恢复状态时redux-sessionstorage不更新节点的属性?

时间:2019-03-14 15:21:14

标签: javascript reactjs redux session-storage

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

我有一个示例应用程序正好复制了此内容:https://github.com/shawninder/sessionstorage-bug

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

还在线托管了here(请稍等一下以解冻)

重新加载页面时会发生问题。 redux-sessionstorage可以从sessionstorage正确还原以前的状态并触发渲染,但是我用于隐藏和显示的style属性没有更新。

换句话说,这可以按预期工作:

<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并显示<div>

为什么redux-sessionstorage在这里不更新style属性,人们通常如何处理呢?

1 个答案:

答案 0 :(得分:0)

@lecstor指出了与此问题相关的话题。

这是服务器端渲染(SSR)的事情。 comment上描述的解决方法Dan Abramov解决了该问题。

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

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

由于Next对客户端的保存状态一无所知,因此它总是将app.showNotice返回到false。您还可以在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>
    )
  }  
}