ReactJS: предупреждение: setState (...): не удается обновить во время существующего перехода состояния
Я пытаюсь преобразовать следующий код из моего вида отображения:
<Button href="#" active={!this.state.singleJourney} onClick={this.handleButtonChange.bind(this,false)} >Retour</Button>
к версии, где привязка находится в конструкторе. Причина в том, что привязка в виде визуализации даст мне проблемы с производительностью, особенно на бюджетных мобильных телефонов.
Я создал следующий код, но я постоянно получаю следующие ошибки (многие из них). Похоже, приложение попадает в цикл:
Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's 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;
6 ответов:
Похоже, вы случайно звоните
handleButtonChange
метод в метод render, вы, вероятно, хотите сделать .если вы не хотите создавать лямбду в обработчике 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>
от реагировал документы передача аргументов обработчикам событий
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button> <button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
Если вы пытаетесь добавить аргументы в обработчик в
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)} /> ) } }
это позволяет избежать написания анонимного функция из вашего обработчика для исправления Исправлена проблема с недостаточным количеством имен параметров в вашем обработчике.
Я получил ту же ошибку, когда я звал
this.handleClick = this.handleClick.bind(this);
в моем конструкторе, когда handleClick не существует
(я стер его и случайно оставил инструкцию привязки "this" в моем конструкторе).
решение = удалить оператор привязки "this".
решение, которое я использую, чтобы открыть Popover для компонентов reactstrap (React Bootstrap 4 components).
class Settings extends Component { constructor(props) { super(props); this.state = { popoversOpen: [] // array open popovers } } // toggle my popovers togglePopoverHelp = (selected) => (e) => { const index = this.state.popoversOpen.indexOf(selected); if (index < 0) { this.state.popoversOpen.push(selected); } else { this.state.popoversOpen.splice(index, 1); } this.setState({ popoversOpen: [...this.state.popoversOpen] }); } render() { <div id="settings"> <button id="PopoverTimer" onClick={this.togglePopoverHelp(1)} className="btn btn-outline-danger" type="button">?</button> <Popover placement="left" isOpen={this.state.popoversOpen.includes(1)} target="PopoverTimer" toggle={this.togglePopoverHelp(1)}> <PopoverHeader>Header popover</PopoverHeader> <PopoverBody>Description popover</PopoverBody> </Popover> <button id="popoverRefresh" onClick={this.togglePopoverHelp(2)} className="btn btn-outline-danger" type="button">?</button> <Popover placement="left" isOpen={this.state.popoversOpen.includes(2)} target="popoverRefresh" toggle={this.togglePopoverHelp(2)}> <PopoverHeader>Header popover 2</PopoverHeader> <PopoverBody>Description popover2</PopoverBody> </Popover> </div> } }