javascript ReactJS 和复杂的 JSON 对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22278598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 22:49:43  来源:igfitidea点击:

ReactJS and complex JSON object

javascriptjsonreactjs

提问by Seif Eddine Mouelhi

I followed ReactJS tutorial, which is quite simple to accomplish more complex stuff.

我遵循了 ReactJS 教程,它很容易完成更复杂的事情。

In my case, I would like to use a complex JSON object, which contains a map, a single value, a list, etc... Here is the code:

就我而言,我想使用一个复杂的 JSON 对象,其中包含地图、单个值、列表等......这是代码:

    var NotificationStatus = React.createClass({
    loadNotificationsFromServer: function() {
      $.ajax({
        url: this.props.url,
        dataType: 'json',
        success: function(data) {
          this.setState({data: data});
          console.log(this.state.data.notificationType);
        }.bind(this)
      });
    },
    getInitialState: function() {
      return {data: {}};
    },
    componentWillMount: function() {
      this.loadNotificationsFromServer();
      setInterval(this.loadNotificationsFromServer, this.props.pollInterval);
    },
    render: function() {
      return (
        <div>
          <li className="dropdown-menu-title">
              <span>You have {this.state.data.notificationCount} notifications</span>            
          </li>
          <Notifications data={this.state.data.notificationType} />
        </div>  
      );
    }
  });



  var Notifications = React.createClass({
    render: function() {
      var notificationNodes = this.props.data.map(function (notif, index) {
        return <Notification key={index}>{notif.type}</Notification>;
      });
      return <li>{notificationNodes}</li>;
      }
  });

  var Notification = React.createClass({
    render: function() {
      return (
        <a href="#">
              <span className="icon blue"><i className={this.props.children == "user" ? 'icon-user' : 'icon-comment-alt'}></i></span>
              <span className="message">{this.props.children}</span>           
              <span className="time">1 min</span>
          </a>
      );
    }
  });

  React.renderComponent(
    <NotificationStatus url="/data/notifications.json" pollInterval={2000} />,
    document.getElementById('notificationbar')
  );

And this is a sample from the JSON:

这是来自 JSON 的示例:

    {
    "notificationCount": "1",
    "notificationType": [
       {
         "type": "update",
         "text": "New Update"
       },
       {
          "type": "user",
          "text": "New User"
       }
     ]
    }

When I try to get notificationType, an error "this.props.data is undefined" is raised at this point

当我尝试获取 notificationType 时,此时会引发错误“this.props.data is undefined”

    var notificationNodes = this.props.data.map(function (notif, index) {

I really don't see what's wrong with the declaration, and when I get the JSON at the ajax level, I do have a map (verified with the console.log).

我真的不明白声明有什么问题,当我在 ajax 级别获取 JSON 时,我确实有一个映射(用 console.log 验证)。

Any help would be great.

任何帮助都会很棒。

Thanks a lot.

非常感谢。

回答by Sophie Alpert

When your component first renders, NotificationStatus's this.state.datawill be {}because that's what's returned from getInitialState. That means that when you render

当您的组件首次呈现时,NotificationStatusthis.state.data将是{}因为这是从getInitialState. 这意味着当你渲染

<Notifications data={this.state.data.notificationType} />

you're passing {}.notificationTypeor undefined:

你正在通过{}.notificationTypeundefined

<Notifications data={undefined} />

So when Notifications first renders, this.props.data isn't a list. It depends on your application what the right fix here is, but perhaps you want to initialize with data: nulland add this to the top of NotificationStatus's render method:

因此,当 Notifications 首次呈现时, this.props.data 不是一个列表。这取决于您的应用程序这里的正确修复是什么,但也许您想初始化data: null并将其添加到 NotificationStatus 的渲染方法的顶部:

if (!this.state.data) {
    return <div>Loading...</div>;
}

回答by captray

In addition to Ben's point, you're also calling loadNotificationsFromServer in componentWillMount. You should call loadNotificationsFromServer and start any timers inside of componentDidMount, as your component has not yet been mounted in the DOM. You can read more here: React Component Lifecycle

除了 Ben 的观点,您还在 componentWillMount 中调用 loadNotificationsFromServer。您应该调用 loadNotificationsFromServer 并在 componentDidMount 内启动任何计时器,因为您的组件尚未安装在 DOM 中。您可以在此处阅读更多信息:React 组件生命周期

Looking back at the code, I'm not entirely sure what your object graph should look like, but in one place it looks like you're trying to iterate over a collection of notifications and in another a single notification.

回顾代码,我不完全确定您的对象图应该是什么样子,但在一个地方看起来您正在尝试迭代一组通知,而在另一个地方则是单个通知。

To alleviate the issue Ben mentioned, you could also initialize your state with default values for notificationType and count ('' and 0) as a quick fix, but the logical operator would work just as well.

为了缓解 Ben 提到的问题,您还可以使用notificationType 和count('' 和0)的默认值初始化状态作为快速修复,但逻辑运算符也可以正常工作。