javascript – 在ReactJS应用程序中将字符串转换为JSON对象时出错

作为我不断努力学习ReactJS的一部分,我正在开发一个简单的页面,它将呈现如下趋势列表:

javascript  – 在ReactJS应用程序中将字符串转换为JSON对象时出错

单击“获取趋势”按钮后,将通过websockets从后端服务器检索趋势列表并显示.它按预期工作.以下是相应的源代码:

import React, { Component } from 'react';
import './App.css';

class TrendRow extends Component {
  render() {
    return (
      <tr>
        <td>{this.props.onerow}</td>
      </tr>
    );
  }
}

class TrendTable extends Component {
  render() {
    var rows = [];
    for (var i=1; i<3; i++) {
      rows.push(<TrendRow key={i} onerow={this.props.trends[i]}/>);
    }
    return (
      <table>
        <thead>
          <tr>
            <th>List of Trends</th>
          </tr>
        </thead>
        <tbody>{rows}</tbody>
      </table>
    );
  }
}

class App extends Component {
  constructor() {
    super();

    this.state = {
      ws: new WebSocket('ws://localhost:8025/websockets/TwitterWSService'),
      getTrendsqueryString: 'GETTRENDS',
      listoftrends: ['{"trend":"#Default","id":"0"}']
    };

    this.handleOnClick = this.handleOnClick.bind(this);
  }

  handleOnClick = (event) => {
    this.state.ws.send(this.state.getTrendsqueryString);
    this.state.ws.onmessage = (event) => {
      this.setState(prevState => ({listoftrends: prevState.listoftrends.concat(event.data)}));
    }
  }

  render() {
    return (
      <div>
          <button onClick={this.handleOnClick}>Get Trends</button>
          <TrendTable trends={this.state.listoftrends} />
      </div>
    );
  }
}

export default App;

现在,当我尝试使用“JSON.parse”将显示的JSON字符串转换为JSON对象时,我会根据解析它的位置获得不同类型的错误.

如果我解析如下所示,

class TrendRow extends Component {
  render() {
    var jsonobject = JSON.parse(this.props.onerow);
    return (
      <tr>
        <td>{jsonobject}</td>
      </tr>
    );
  }
}

我得到以下错误:

“SyntaxError: Unexpected token u in JSON at position 0

var jsonobject = JSON.parse(this.props.onerow);

…”

快速谷歌搜索错误消息返回以下讨论,但不清楚如何将解决方案应用于我的用例:

uncaught syntaxerror unexpected token U JSON

我知道错误是由于值’this.props.onerow’在初始渲染期间未定义而JSON.parse()试图解析此对象.即使使用默认字符串初始化“listoftrends”对象也无法解决错误.

如果另一方面我JSON.parse()如下所示,

  handleOnClick = (event) => {
    this.state.ws.send(this.state.getTrendsqueryString);
    this.state.ws.onmessage = (event) => {
      var jsonobject = JSON.parse(event.data);
      this.setState(prevState => ({listoftrends: prevState.listoftrends.concat(jsonobject)}));
    }
  }

我收到错误消息:

Objects are not valid as a React child…

谷歌搜索让我陷入另一个兔子洞!有人可以为我提供任何其他解决方案吗?

解决方法:

看看你的代码(以及你刚刚学习的笔记),让我添加一些评论,告诉你如何改进它.

>使用带有类属性的箭头函数可确保始终使用组件作为此值调用方法,这意味着此处的手动绑定是多余的.所以你可以摆脱下面的界限.

this.handleOnClick = this.handleOnClick.bind(this);
>还要摆脱TrendTable中丑陋的for循环,并将其替换为map功能.

class TrendTable扩展了Component {
  render(){
    回来(
      &LT表>
        < tbody> {this.props.trends.map(trend =>
          < TrendRow key = {i} onerow = {trend} />)}
        &LT / tbody的&GT
      &LT /表>
    );
  }
}

You can read more关于你要避免常规循环的替代方案.
>对于预填充趋势数组,更好的方法是使用componentDidMount反应生命周期方法.深入深入查看this文章.

我认为最好创建更新按钮(而不是获取趋势),如果需要,应该使用后端的新部分完全重写您的趋势列表(但确定这一点取决于您).
>现在,如果只需要初始化默认状态,则不必在组件内部使用构造函数方法,因此可以使用
state = {….};只是在你的组件内部没有使用构造函数.但请确保您使用的是stage-2 preset.

因此,考虑到上面的评论,这里是App组件:

class App extends Component {

  state = {
      ws: new WebSocket('ws://localhost:8025/websockets/TwitterWSService'),
      getTrendsqueryString: 'GETTRENDS',
      listoftrends: [] // you can add default trend record if you need it
    };
  };

  componentDidMount() {
    this.fetchTrends();
  }

  fetchTrends = (completeUpdate = false) => { 
    this.state.ws.send(this.state.getTrendsqueryString);
    this.state.ws.onmessage = (event) => {
      this.setState(prevState => (
        { listoftrends: !completeUpdate ? prevState.listoftrends.concat(event.data) : event.data }
      ));
    }    
  };

  updateTrends = () => {
    this.fetchTrends(true); //in that case you'd like to completely update the list
  }

}
  render() {
    return (
      <div>
        <button onClick={this.updateTrends}>Update trends</button>
        <TrendTable trends={this.state.listoftrends} />
      </div>
    );
  }
}

>关于你的问题本身.正如许多其他人已经提到的那样,是的,不可能在JSX中使用一个对象,所以你必须先将它转换(例如转换为数组).

例如.

var array = Object.values(jsonobject).map(value => ...);

// and then in JSX
<div>{array}</div>

希望这一切都有道理.

上一篇:javascript – 在React中的现有状态转换错误期间无法更新


下一篇:前端笔记之React(一)初识React&组件&JSX语法