如何通过反应恢复后退按钮上的状态

Sys*_*ral 7 reactjs react-router

如果我有一个简单的react组件来记录按钮的点击次数,那么每次点击都会记录一个新的历史记录状态而不更改url.当用户点击回来时,如何将状态恢复到原样?

我可以在这里使用本机JavaScript历史记录对象,但是当用户转换回第一个状态并从另一个组件返回到此状态的最后一个状态时,它会失败.

我怀疑使用react-router(1.0)有更好的方法吗?

import React, { Component } from 'react';

export default class Foo extends Component {
  state = {
    clickCount: 0,
  };

  componentWillMount() {
    window.onpopstate = (event) => {
      if (event.state.clickCount) {
        this.setState({ clickCount: event.state.clickCount });
      }
    };
  }

  onClick() {
    const newClickCount = this.state.clickCount + 1;
    const newState = { clickCount: newClickCount };
    this.setState(newState);
    history.pushState(newState, '');
  }

  render() {

    return (
      <div>
        <button onClick={this.onClick.bind(this)}>Click me</button>
        <div>Clicked {this.state.clickCount} times</div>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

gri*_*edj 4

localStorage 甚至 cookie 都是选项,但可能不是最好的方法。您应该将计数存储在数据库中,这样您就可以将构造函数中的初始状态设置为数据库中保存的最后一个值。

如果您只需要在客户端(而不是在数据库中)保留计数,另一种选择是使用闭包。

// CountStore.js
var CountStore = (function() {
  var count = 0;

  var incrementCount = function() {
    count += 1;
    return count;
  };

  var getCount = function() {
    return count;
  };

  return {
    incrementCount: incrementCount,
    getCount: getCount
  }

})();

export default CountStore;
Run Code Online (Sandbox Code Playgroud)

所以你的代码将更改为以下内容。

import React, { Component } from 'react';
import CountStore from './CountStore'; 

export default class Foo extends Component {
  state = {
    clickCount: CountStore.getCount()
  };

  componentWillMount() {
    window.onpopstate = (event) => {
      if (event.state.clickCount) {
        this.setState({ clickCount: event.state.clickCount });
      }
    };
  }

  onClick() {
    const newClickCount = CountStore.incrementCount();
    const newState = { clickCount: newClickCount };
    this.setState(newState);
  }

  render() {

    return (
      <div>
        <button onClick={this.onClick.bind(this)}>Click me</button>
        <div>Clicked {this.state.clickCount} times</div>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

可能有更干净的使用方式react-router,但这是一个选项。