reactjs - 未捕获的TypeError:无法读取未定义的属性“map” [英] reactjs - Uncaught TypeError: Cannot read property 'map' of undefined
问题描述
我正在尝试使用json返回的内容不仅填充我的列表,而且在创建新列表时允许选择父级。
I'm trying to use the contents of a json return to not only populate my list, but when creating a new list to allow the selection of a parent.
我的导航列表即将出现,但当我点击创建新列表时,它会出现以下错误:
I have the list coming up in my Navigation but when I click on "Create New List" it gives the following error:
Uncaught TypeError: Cannot read property 'map' of undefined
在代码的这一特定部分出现:
Which occurs on this particular part of code:
render: function() {
var navNodes = this.props.data.map(function(nav) {
return (
React.createElement(NavItems, {name: nav.name, key: nav.id})
);
});
return (
React.createElement(Input, {
label: "Parent List",
ref: "input",
value: this.state.value,
bsStyle: this.state.validationState,
hasFeedback: true,
help: this.state.hint,
onChange: this.handleChange,
type: "select"},
this.renderPlaceholder(),
navNodes
)
);
代码:
var Bootstrap = ReactBootstrap;
var Input = ReactBootstrap.Input;
var NavItems = React.createClass({
render: function() {
return (
<option value={1}>{navNodes}</option>
);
}
});
var NavItem = React.createClass({
render: function() {
return (
<li><a href="#">{this.props.name}</a></li>
);
}
});
var NavList = React.createClass({
render: function() {
var navNodes = this.props.data.map(function(nav) {
return (
<NavItem name={nav.name} key={nav.id}></NavItem>
);
});
return (
<ul className="nav">
<li className="current"><a href="#"><i className="glyphicon glyphicon-home"></i> Lists</a></li>
{navNodes}
</ul>
);
}
});
var NewListButton = React.createClass({
render: function() {
return (
<a {...this.props}
href="javascript:;"
role="button"
className={(this.props.className || '') + ' btn'}
/>
);
}
});
var ListNameInput = React.createClass({
getInitialState: function() {
return {
value: '',
hint: null,
validationState: null
};
},
handleChange: function() {
var newValue = this.refs.input.getValue(),
hint = null,
validationState = null,
length = newValue.length;
if (length > 2) {
validationState = 'success';
} else {
validationState = 'error';
if (length) {
hint = 'The name must be at least 3 characters long.';
} else {
hint = 'This value is required.';
}
}
this.setState({
value: newValue,
hint: hint,
validationState: validationState
});
},
isValid: function() {
return ('success' === this.state.validationState);
},
render: function() {
return (
<Input
label='Name'
ref='input'
value={this.state.value}
placeholder='Enter List Name'
bsStyle={this.state.validationState}
hasFeedback
help={this.state.hint}
onChange={this.handleChange}
type='text' />
);
}
});
var ListDescriptionInput = React.createClass({
getInitialState: function() {
return {
value: '',
hint: null,
validationState: null
};
},
handleChange: function() {
var newValue = this.refs.input.getValue(),
hint = null,
validationState = null,
length = newValue.length;
if (length > 2) {
validationState = 'success';
} else {
validationState = 'error';
if (length) {
hint = 'The description must be at least 3 characters long.';
} else {
hint = 'This value is required.';
}
}
this.setState({
value: newValue,
hint: hint,
validationState: validationState
});
},
isValid: function() {
return ('success' === this.state.validationState);
},
render: function() {
return (
<Input
label='Description'
ref='input'
value={this.state.value}
placeholder='Enter Description'
bsStyle={this.state.validationState}
hasFeedback
help={this.state.hint}
onChange={this.handleChange}
type='text' />
);
}
});
var WidgetListSelect = React.createClass({
getInitialState: function() {
return {
value: 0,
hint: null,
validationState: null
};
},
handleChange: function() {
var newValue = Number(this.refs.input.getValue()),
hint = null,
validationState = null;
if (0 === newValue) {
validationState = 'error';
hint = 'You must select an parent list.';
} else {
validationState = 'success';
}
this.setState({
value: newValue,
hint: hint,
validationState: validationState
});
},
isValid: function() {
return ('success' === this.state.validationState);
},
renderPlaceholder: function() {
if (0 !== this.state.value)
return null;
// Show placeholder only prior to a value being selected
return (
<option value={0}>
Please select a Parent List
</option>
);
},
render: function() {
var navNodes = this.props.data.map(function(nav) {
return (
<NavItems name={nav.name} key={nav.id}></NavItems>
);
});
return (
<Input
label='Parent List'
ref='input'
value={this.state.value}
bsStyle={this.state.validationState}
hasFeedback
help={this.state.hint}
onChange={this.handleChange}
type='select'>
{this.renderPlaceholder()}
{navNodes}
</Input>
);
}
});
var CreateNewListForm = React.createClass({
handleSubmit: function() {
var isValid =
!!(this.refs.nameInput.isValid()
& this.refs.descriptionInput.isValid()
& this.refs.widgetlistSelect.isValid());
if (isValid) {
this.props.closeModal();
} else {
// Force validation of each element to show errors to user
this.refs.nameInput.handleChange();
this.refs.descriptionInput.handleChange();
this.refs.widgetlistSelect.handleChange();
}
},
render: function() {
return (
<div>
<ListNameInput
ref='nameInput' />
<ListDescriptionInput
ref='descriptionInput' />
<WidgetListSelect
ref='widgetlistSelect' />
<Bootstrap.ButtonToolbar>
<Bootstrap.Button
onClick={this.handleSubmit}>
Save
</Bootstrap.Button>
<Bootstrap.Button
onClick={this.props.closeModal}>
Cancel
</Bootstrap.Button>
</Bootstrap.ButtonToolbar>
</div>
);
}
});
var NavBox= React.createClass({
loadNavsFromServer: function() {
$.ajax({
url: "http://servername/api/widgetlists/?format=json",
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error("http://servername/api/widgetlists/?format=json", status, err.toString());
}.bind(this)
});
},
handleListSubmit: function(comment) {
// TODO: submit to the server and refresh the list
},
getInitialState: function() {
return {
modalVisible: false,
data: []};
},
onClick: function() {
this.setState({modalVisible: true});
},
hideModal: function() {
this.setState({modalVisible: false});
},
renderModal: function() {
return (
<Bootstrap.Modal
show={this.state.modalVisible}
onHide={this.hideModal}>
<Bootstrap.Modal.Body>
<CreateNewListForm
closeModal={this.hideModal} />
</Bootstrap.Modal.Body>
</Bootstrap.Modal>
);
},
componentDidMount: function() {
this.loadNavsFromServer();
},
render: function() {
return (
<div className="col-md-2">
<div className="sidebar content-box" style={{display: "block"}}>
<NavList data={this.state.data} />
{this.renderModal()}
<Bootstrap.Button onClick={this.onClick}>
Create New List
</Bootstrap.Button>
</div>
</div>
);
}
});
module.exports = {
NavBox: NavBox
}
推荐答案
您需要中的返回值getDefaultProps
。
https://facebook.github.io/react/docs /reusable-components.html#default-prop-values
getDefaultProps: function() {
return {
data: []
};
}
此外,定义您的道具类型也是一种好习惯:
Also, it's good practice to define your prop types too:
propTypes: {
data: React.PropTypes.array.isRequired
}
虽然我不喜欢ES6 / 7级糖,因为我不喜欢那种规格(这对你的JS思维来说就像糖一样不健康)但是,如果您喜欢它,那么它们也可以将它们定义为 static
property defaultProps
。
Whilst I'd avoid ES6/7 Class sugar as I'm not a fan of that specification (it's unhealthy for your JS mind like sugar), nevertheless, if you like it then their is also a way to define these as static
property defaultProps
.
class Foo extends React.Component {
static defaultProps = {
bar: React.PropTypes.array.isRequired
}
}
这篇关于reactjs - 未捕获的TypeError:无法读取未定义的属性“map”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!