setState не является постоянным - PullRequest
0 голосов
/ 03 апреля 2019

Я пытаюсь создать боковое меню, в котором есть складные параметры.

Ниже мой код:

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

Когда я распечатал this.state.fprActive в методе render (), я увидел следующее:

  • Установка fprActive с true на false
  • сделать ложь
  • сделать истинным

Почему у моего fprActive автоматически устанавливается значение true, когда я нажимаю только один раз?

1 Ответ

4 голосов
/ 03 апреля 2019

Я не могу воспроизвести проблему на этом конце, но симптом говорит, что ваша страница обновляется, когда вы нажимаете на якорь, потому что вы не препятствует действию по умолчанию. Имейте toggleFPR вызов preventDefault на объекте события, который это получает:

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

Отдельно: вы нарушаете одно из фундаментальных правил Реакта здесь:

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

Если вы этого не сделаете, он будет работать большую часть времени, а иногда и будет трудно диагностировать.

...