setState 不是永久的

setState is not permanent

我正在尝试创建一个具有可折叠选项的侧边菜单。

下面是我的代码:

export default class CRSideMenu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      fprActive: true
    };
    autoBind(this);
  }

  toggleFPR() {
    console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive);
    this.setState({
      fprActive: !this.state.fprActive
    });
  }

  render() {
    console.log('render', this.state.fprActive);
    return (
      <ul className='list-group list-group-nav'>
        <li>
          <a 
            href='#' 
            className={classnames('list-group-item', this.state.fprActive && 'active', 'has-subnav')}
            onClick={this.toggleFPR} >
            FPR
          </a>
          <ul className='list-group list-group-nav'>
            <li>
              <a href='' className='list-group-item'>FR</a>
            </li>
          </ul>
        </li>
      </ul>
    );
  }
}

当我在 render() 方法中打印出 this.state.fprActive 时,我看到以下内容:

为什么我的 fprActive 会在我只点击一次时自动退回到 'true'?

我无法在这一端重现该问题,但症状表明当您单击锚点时您的页面正在刷新,因为您没有阻止默认操作。让 toggleFPR 对其接收的事件对象调用 preventDefault

toggleFPR(event) {
//        ^^^^^ ------------ ***
  event.preventDefault(); // ***
  console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive);
  this.setState({
    fprActive: !this.state.fprActive
  });
}

另外:您在这里破坏了 the fundamental React rules 之一:

console.log('Setting fprActive from ', this.state.fprActive, ' to ', !this.state.fprActive);
this.setState({
  fprActive: !this.state.fprActive
});

根据现有状态设置状态时,您必须使用回调版本,而不是您将对象传入的版本:

this.setState(({fprActive}) => {
  console.log('Setting fprActive from ', fprActive, ' to ', !fprActive);
  return {fprActive: !fprActive};
});

如果你不这样做,它大部分时间都会工作,有时会以难以诊断的方式失败。