reactjs - 未捕获的TypeError:无法读取未定义的属性“map” [英] reactjs - Uncaught TypeError: Cannot read property 'map' of undefined

查看:114
本文介绍了reactjs - 未捕获的TypeError:无法读取未定义的属性“map”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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
  }
}

https://facebook.github.io/react/blog /2015/01/27/react-v0.13.0-beta-1.html#es7-property-initializers

这篇关于reactjs - 未捕获的TypeError:无法读取未定义的属性“map”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆