Я пытаюсь реорганизовать следующий код из представления рендеринга:
<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;
Похоже, вы случайно вызываете метод 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>
У меня такая же ошибка, когда я звонил
this.handleClick = this.handleClick.bind(this);
в моем конструкторе, когда handleClick не существует
(я удалил его и случайно оставил оператор привязки "this" в моем конструкторе).
Решение = удалить оператор привязки "this".
Если вы пытаетесь добавить аргументы в обработчик в 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)} />
)
}
}
это позволяет избежать написания анонимной функции из вашего обработчика, чтобы исправить проблему, не поставляя достаточное количество имен параметров в вашем обработчике.