使用浏览器 'back' 按钮时 React 中的状态和显示不一致

inconsistent state and display in React when using browser 'back' button

我在 Rails 5.1 应用程序中使用 React 16.1.1(带有 react-rails gem)。

特定页面上的 React 组件工作正常,除非使用浏览器 'back' 按钮返回此页面(使用 firefox / chrome / safari 测试)。在那种情况下,显示与组件的状态不一致。我已经设置了一个问题演示https://lit-bastion-28654.herokuapp.com/

重现步骤

  1. 在/page1
  2. 单击 'selection mode' 按钮,它会将 'selectionMode' 设置为 true
  3. 点击'page 2'
  4. 使用 'back' 按钮返回第 1 页
  5. 预期行为:按钮为灰色(组件加载时 selectionMode 重置为 false)。观察到的行为:按钮仍然是蓝色的?!

在那里,你可以看到按钮是蓝色的,好像 selectionMode 是真的,但是反应浏览器插件显示 selectionMode 是假的。 React浏览器插件显示错误信息:显示按钮没有'btn-primary' class(如果selectionMode为false是正常的),但你可以明显看到DOM ,它有 'btn-primary' class,因为它看起来是蓝色的。

这是我的代码:

page1.html.erb:

<%= react_component("EditableCardList", { editable: true }) %>

editable_card_list.js.jsx:

class EditableCardList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectionMode: false
    };

    this.toggleSelectionMode = this.toggleSelectionMode.bind(this);
  }


  toggleSelectionMode() {
    this.setState(prevState => ({ selectionMode: !prevState.selectionMode }));
  }


  render() {
    if (this.props.editable === true)
      return (
        <div>
          <div className="row card-buttons">
            <div className="col-md-12">
              <div className="pull-left">
                <ManageCardsButtons
                  selectionMode={this.state.selectionMode}
                  toggleSelectionMode={this.toggleSelectionMode}
                />
              </div>
            </div>
          </div>
        </div>
      )
  }
}

manage_cards_buttons.js.jsx:

class ManageCardsButtons extends React.Component {
  constructor(props) {
    super(props);
  }


  render() {
    return (
      <span>
        <button type="button" className={`btn btn-default btn-sm ${this.props.selectionMode ? 'btn-primary' : ''}`}  onClick={this.props.toggleSelectionMode}>Selection mode</button>

        { this.props.selectionMode && <span>selection mode</span> }
      </span>
    )
  }
}

所以我的问题是:如何确保在浏览器中使用 'back' 后,按钮正确重新呈现(并且显示为灰色而不是蓝色)?

这个问题可能与 turbolinks 和缓存有关,但我还没有弄清楚。

当您返回 page1 时,组件重新呈现,并设置默认的 selectionMode,在您的情况下为 false。

  1. 你可以使用 redux。
  2. 您可以将 selectionMode 保存到您的 localStorage 当它改变时,默认情况下从 存储空间。

React 和 TurboLinks 冲突,所以我的最终解决方案是在该特定页面上禁用 TurboLinks 缓存。