ReactJS: Предупреждение: setState (…): невозможно обновить во время существующего перехода состояния

96

Я пытаюсь реорганизовать следующий код из представления рендеринга:

<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange.bind(this,false)} >Retour</Button>

к версии, где bind находится внутри конструктора. Причиной этого является то, что привязка в представлении рендеринга даст мне проблемы с производительностью, особенно на мобильных телефонах с низким доходом.

Я создал следующий код, но я постоянно получаю следующие ошибки (многие из них). Похоже, приложение попадает в цикл:

Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

Ниже приведен код, который я использую:

var React = require('react');
var ButtonGroup = require('react-bootstrap/lib/ButtonGroup');
var Button = require('react-bootstrap/lib/Button');
var Form = require('react-bootstrap/lib/Form');
var FormGroup = require('react-bootstrap/lib/FormGroup');
var Well = require('react-bootstrap/lib/Well');

export default class Search extends React.Component {

    constructor() {
        super();

        this.state = {
            singleJourney: false
        };

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

    handleButtonChange(value) {
        this.setState({
            singleJourney: value
        });
    }

    render() {

        return (
            <Form>

                <Well style={wellStyle}>

                    <FormGroup className="text-center">

                        <ButtonGroup>
                            <Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange(false)} >Retour</Button>
                            <Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChange(true)} >Single Journey</Button>
                        </ButtonGroup>
                    </FormGroup>

                </Well>

            </Form>
        );
    }
}

module.exports = Search;
Теги:
constructor

3 ответа

168
Лучший ответ

Похоже, вы случайно вызываете метод handleButtonChange в методе рендеринга, скорее всего, хотите сделать onClick={() => this.handleButtonChange(false)}.

Если вы не хотите создавать лямбда в обработчике onClick, я думаю, вам нужно иметь два связанных метода: по одному для каждого параметра.

В constructor:

this.handleButtonChangeRetour = this.handleButtonChange.bind(this, true);
this.handleButtonChangeSingle = this.handleButtonChange.bind(this, false);

И в методе render:

<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChangeSingle} >Retour</Button>
<Button href="#" active={this.state.singleJourney} onClick={this.handleButtonChangeRetour}>Single Journey</Button>
  • 0
    Я пробовал это решение, и оно работает. Но я не вижу это решение онлайн как предпочтительное решение. Что я хочу сделать, так это то, что моя привязка находится вне представления рендера. В этом решении this.handleButtonChange = this.handleButtonChange.bind (this); в конструкторе больше не нужен, означает ли это, что моя привязка снова в моем представлении рендеринга?
  • 2
    Возможно, что происходит, когда я устанавливаю активное состояние, он запускает OnClick, что приводит к циклу. Есть ли способ установить активное состояние, не вызывая onClick?
Показать ещё 8 комментариев
1

У меня такая же ошибка, когда я звонил

this.handleClick = this.handleClick.bind(this);

в моем конструкторе, когда handleClick не существует

(я удалил его и случайно оставил оператор привязки "this" в моем конструкторе).

Решение = удалить оператор привязки "this".

0

Если вы пытаетесь добавить аргументы в обработчик в recompose, убедитесь, что вы правильно определяете свои аргументы в обработчике. Это, по сути, каррическая функция, поэтому вы должны быть уверены в правильном количестве аргументов. Эта страница имеет хороший пример использования аргументов с обработчиками.

Пример (по ссылке):

withHandlers({
  handleClick: props => (value1, value2) => event => {
    console.log(event)
    alert(value1 + ' was clicked!')
    props.doSomething(value2)
  },
})

для вашего ребенка HOC и в родительском

class MyComponent extends Component {
  static propTypes = {
    handleClick: PropTypes.func, 
  }
  render () {
    const {handleClick} = this.props
    return (
      <div onClick={handleClick(value1, value2)} />
    )
  }
}

это позволяет избежать написания анонимной функции из вашего обработчика, чтобы исправить проблему, не поставляя достаточное количество имен параметров в вашем обработчике.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню