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

下面是我的代码:

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设置为false

呈现真实


当我只单击一次时,为什么我的fprActive会自动倒退为“ true”?

最佳答案

我目前无法复制该问题,但症状是单击锚点时您的页面正在刷新,因为您没有阻止默认操作。在接收到的事件对象上调用toggleFPR

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


如果不这样做,它将在大多数时间都有效,并且有时会以难以诊断的方式失败。

10-07 21:59