Я создаю динамический список для меню в ReactJs. Данные для каждого пункта меню выбиваются из файла JSON через AJAX. Я хочу, чтобы меню закрывалось при нажатии элемента меню. Я перечисляю весь список пропеллера "whenClicked" при нажатии на один из пунктов меню. Ниже приведен код:
var MenuList = React.createClass({
getInitialState: function() {
return {data: []}
},
componentWillMount: function() {
$.ajax({
url: 'http://10.0.0.97:8888/public-code/data/data.json',
dataType: 'json',
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, error) {
var err = JSON.parse(xhr.responseText);
console.log(err.Message);
}
});
},
render: function() {
var list = this.state.data.map(function(menuItemProps) {
return <MenuItem onClick={this.props.whenClicked} {...menuItemProps} key={menuItemProps.id} />
});
return (
<ul id="menu-list">
{list}
</ul>
)
}
});
Затем "whenClicked" поддерживает функцию в родительском меню "handleClick", которая изменяет состояние меню и закрывает его, если он открыт. Вот код для компонента родительского меню, который содержит компонент MenuList выше:
module.exports = React.createClass({
getInitialState: function() {
return {open: false, mobi: false}
},
handleClick: function() {
this.setState({open: !this.state.open})
},
closeOnMobiScroll: function() {
/*
if(this.state.mobi === false) {
this.setState({open: false})
}
*/
},
updateDimensions: function() {
$(window).width() >= 767 ? this.setState({mobi: true}) : this.setState({mobi: false});
},
componentWillMount: function() {
this.updateDimensions();
},
componentDidMount: function() {
$(window).on("resize", this.updateDimensions);
},
componentWillUnmount: function() {
$(window).on("resize", this.updateDimensions);
},
render: function() {
return (
<div id="menu" className={(this.state.open ? 'open' : '')} >
<div id="menu-inner-wrap">
<MenuTitle />
<MenuToggle whenClicked={this.handleClick}/>
<MenuList whenClicked={this.handleClick}/>
</div>
</div>
)
}
});
Проблема заключается в том, что весь сценарий прерывается перед вызовом AJAX, и я получаю следующую ошибку:
Uncaught TypeError: Cannot read property 'whenClicked' of undefined
Поскольку я не вижу свое сообщение об ошибке AJAX в консоли, я подозреваю, что проблема в том, что React пытается подключить
onClick={this.props.whenClicked}
перед загрузкой моих данных.
Есть ли способ решить это? Есть ли что-то еще, что мне не хватает?
Проблема не имеет ничего общего с вызовом Ajax или с React.
Внутри обратного вызова вы переходите к .map
, this
относится к глобальному объекту, а не к компоненту. Глобальный объект не имеет свойства prop
, следовательно, ошибки.
Вы можете использовать .bind
для привязки this
значения функции к компоненту:
this.state.data.map(function(...) { ... }.bind(this));
Дополнительная информация: Как получить доступ к правильному "этому" контексту внутри обратного вызова?
Похоже, вам нужно привязать надлежащий контекст для функции сопоставления. Пытаться:
var list = this.state.data.map( function(menuItemProps) {
return <MenuItem onClick={this.props.whenClicked} {...menuItemProps} key={menuItemProps.id} />
}.bind(this) );