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

时间:2016-02-12 16:45:43

标签: reactjs react-router

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

我可以在这里使用原生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>
    );
  }
}

2 个答案:

答案 0 :(得分:1)

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;

因此,您的代码将更改为以下内容。

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>
    );
  }
}

使用react-router可能会更简洁,但这是一种选择。

答案 1 :(得分:0)

一个例子:

import React, {Component} from "react";
import {NavLink} from "react-router-dom";

interface Props {
}

interface State {
    count: number
}

export default class About extends Component<Props, State> {

    UNSAFE_componentWillMount(): void {
        this.setState(Object.getPrototypeOf(this).constructor.STATE || {});
    }

    componentWillUnmount(): void {
        Object.getPrototypeOf(this).constructor.STATE = this.state;
    }

    constructor(props: Props) {
        super(props);
        this.state = {count: 0}
    }

    render() {
        const {count} = this.state;
        return <div style={{width: "100%", height: "100%", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "space-evenly", fontSize: "2em"}}>
            <span>Count: {count}</span>
            <button onClick={() => this.setState({count: count + 1})}>PLUS ONE</button>
            <NavLink to="/">Redirect to HOME</NavLink>
        </div>
    }
}