Javascript 如何使用ReactJS显示JSON对象中的数据?

Javascript 如何使用ReactJS显示JSON对象中的数据?,javascript,reactjs,Javascript,Reactjs,新程序员在这里学习JS。我有一些代码使用axios发出HTTP请求,从本地文件获取XMLData。然后在响应中,我使用XMLJS将xml数据转换为JSON对象。然后,我采用jsonObj并使用setState()将其保存到一个状态 我有一个函数renderTableRows(),它应该返回JSX以在浏览器上显示我的JSON数据。我解构了状态并尝试从renderTableRows()控制台日志,但当我尝试访问users.result.body时,我得到 TypeError:无法读取未定义的属性“b

新程序员在这里学习JS。我有一些代码使用axios发出HTTP请求,从本地文件获取XMLData。然后在响应中,我使用XMLJS将xml数据转换为JSON对象。然后,我采用
jsonObj
并使用
setState()
将其保存到一个状态

我有一个函数
renderTableRows()
,它应该返回JSX以在浏览器上显示我的JSON数据。我解构了状态并尝试从
renderTableRows()
控制台日志,但当我尝试访问
users.result.body时,我得到

TypeError:无法读取未定义的属性“body”

当我从
then()
中的
componentDidMount()
执行此操作时,我能够访问数据。我还在代码底部包含了我正在阅读的数据摘录

我想使用
map()
遍历所有行数组属性。任何帮助都将不胜感激

class Table extends Component {
  constructor(props) {
    super(props)
    this.state = {
      users: []
    }
  }

  async componentDidMount() {
    axios.get(XMLData, {
      "Content-Type": "application/xml; charset=utf-8"
    })
    .then((response) => {
      var jsonObj = convert.xml2js(response.data,{compact:true, spaces: 4});
      this.setState({users:jsonObj});
      //console.log(this.state.users.result.body.row[0].col[0]);
    });
  }

  renderTableHeader = () => {
   return <th>
            <td>Division Full Path</td>
            <td>Billable Hours</td>
            <td>Vacation Hours Only</td>
            <td>Total Hours</td>
          </th>
  }

  renderTableRows = () => {
    const {users} = this.state
   console.log(users.result.body);
    return <h1>Hello from table rows</h1>
  }

  render() {
    //const { users } = this.state

    return <table>
              <thead>
                <tr>
                  {this.renderTableHeader()}
                </tr>
              </thead>
              <tbody>
                <tr>
                  {this.renderTableRows()}
                </tr>
              </tbody>
          </table>
  }  

 "header": {
    "col": [
        {
            "label": {
                "_text": "Counter Source Date"
            }
        },
        {
            "label": {
                "_text": "Employee Id"
            }
        },
        {
            "label": {
                "_text": "Counter Hours"
            }
        },
        {
            "label": {
                "_text": " Division Full Path"
            }
        },
        {
            "label": {
                "_text": " Projects/Equip/Vessels\nBillable"
            }
        },
        {
            "label": {
                "_text": "Counter Name"
            }
        }
    ]
}  

"body": {
        "row": [
            {
                "col": [
                    {
                        "_text": "01/01/2021"
                    },
                    {
                        "_text": "2183"
                    },
                    {
                        "_text": "8.00"
                    },
                    {
                        "_text": "01 - Fort Lauderdale/Salvage"
                    },
                    {
                        "_text": "No"
                    },
                    {
                        "_text": "Holiday"
                    }
                ]
            }
          ]
        }
类表扩展组件{
建造师(道具){
超级(道具)
此.state={
用户:[]
}
}
异步组件didmount(){
axios.get(XMLData{
“内容类型”:“应用程序/xml;字符集=utf-8”
})
。然后((响应)=>{
var jsonObj=convert.xml2js(response.data,{compact:true,spaces:4});
this.setState({users:jsonObj});
//console.log(this.state.users.result.body.row[0].col[0]);
});
}
renderTableHeader=()=>{
返回
分区完整路径
计费小时数
仅限假期
总小时数
}
renderTableRows=()=>{
const{users}=this.state
console.log(users.result.body);
从表行返回Hello
}
render(){
//const{users}=this.state
返回
{this.renderTableHeader()}
{this.renderTableRows()}
}  
“标题”:{
“col”:[
{
“标签”:{
“_text”:“计数器来源日期”
}
},
{
“标签”:{
“_text”:“员工Id”
}
},
{
“标签”:{
“_text”:“柜台时间”
}
},
{
“标签”:{
“_text”:“分割完整路径”
}
},
{
“标签”:{
“\u text”:“项目/设备/船舶\n可更改”
}
},
{
“标签”:{
“_text”:“计数器名称”
}
}
]
}  
“正文”:{
“行”:[
{
“col”:[
{
“_text”:“01/01/2021”
},
{
“_text”:“2183”
},
{
“_text”:“8.00”
},
{
“_text”:“01-劳德代尔堡/救助”
},
{
“_text”:“否”
},
{
“_text”:“假日”
}
]
}
]
}
问题 初始状态与在
renderTableRows
中访问它的方式不匹配

this.state = {
  users: []
}
这里的
this.state.users
是一个数组,因此
this.state.users.result
未定义。在您尝试访问
body
属性并且抛出错误
TypeError:无法读取未定义的
的属性“body”之前,这是正常的

解决办法 您可以从有效的初始状态开始:

this.state = {
  users: {
    result: {}
  }
}
或者在
renderTableRows
中使用一组保护子句:

renderTableRows = () => {
  const { users } = this.state
  console.log(users.result && users.result.body);
  return <h1>Hello from table rows</h1>
}
更新 我建议将您的状态设置为
jsonObj.result
properties,这样您就不需要在每次渲染时访问
result
属性,它只是缩短了对.Map
this.state.users.headerColumns
标题列的访问,并将
this.state.rows
映射到每一行,另外映射行列

class Table extends Component {
  constructor(props) {
    super(props);
    this.state = {
      users: {
        headerColumns: [],
        rows: [],
      }
    };
  }

  async componentDidMount() {
    axios
      .get(XMLData, {
        "Content-Type": "application/xml; charset=utf-8"
      })
      .then((response) => {
        var jsonObj = convert.xml2js(response.data, {
          compact: true,
          spaces: 4
        });
        this.setState({ users: {
          headerColumns: jsonObj.header.col,
          rows: jsonObj.body.row
        } });
      });
  }

  renderTableHeader = () => {
    const { users: { headerColumns } } = this.state;
    return (
      <th>
        {headerColumns.map(col => (
          <td key={col.label._text}>{col.label._text}</td>
        ))}
        <td>Total Hours</td>
      </th>
    );
  };

  renderTableRows = () => {
    const { users: { rows } } = this.state;
    return rows.map((row, index) => {
      let computedTotal;
      return (
      <tr key={index}>
        {row.col.map((value, index) => {
          // compute time total from row data
          return (
            <td key={index}>{value}</td>
            );
          })}
          <td>{computedTotal}</td>
      </tr>
    )});
  };

  render() {
    return (
      <table>
        <thead>
          <tr>{this.renderTableHeader()}</tr>
        </thead>
        <tbody>
          {this.renderTableRows()}
        </tbody>
      </table>
    );
  }
}
类表扩展组件{
建造师(道具){
超级(道具);
此.state={
用户:{
标题栏:[],
行:[],
}
};
}
异步组件didmount(){
axios
.get(XMLData{
“内容类型”:“应用程序/xml;字符集=utf-8”
})
。然后((响应)=>{
var jsonObj=convert.xml2js(response.data{
是的,
空间:4
});
此.setState({用户:{
headerColumns:jsonObj.header.col,
行:jsonObj.body.row
} });
});
}
renderTableHeader=()=>{
const{users:{headerColumns}}=this.state;
返回(
{headerColumns.map(列=>(
{col.label.\u text}
))}
总小时数
);
};
renderTableRows=()=>{
const{users:{rows}}=this.state;
返回rows.map((行,索引)=>{
让我们计算总数;
返回(
{row.col.map((值,索引)=>{
//从行数据计算总时间
返回(
{value}
);
})}
{computedTotal}
)});
};
render(){
返回(
{this.renderTableHeader()}
{this.renderTableRows()}
);
}
}

谢谢您的帮助!我已经更新了状态并添加了从对象获得的数据。我添加了header属性,该属性具有一个
col
数组,该数组包含6个包含表格标题的属性。正文包含一个
数组,其中包含10000个数组
col
,其中包含6个与he匹配的对象我希望能够通过<
renderTableRows = () => {
  const {users} = this.state
  return users.map(user => (....))
}
class Table extends Component {
  constructor(props) {
    super(props);
    this.state = {
      users: {
        headerColumns: [],
        rows: [],
      }
    };
  }

  async componentDidMount() {
    axios
      .get(XMLData, {
        "Content-Type": "application/xml; charset=utf-8"
      })
      .then((response) => {
        var jsonObj = convert.xml2js(response.data, {
          compact: true,
          spaces: 4
        });
        this.setState({ users: {
          headerColumns: jsonObj.header.col,
          rows: jsonObj.body.row
        } });
      });
  }

  renderTableHeader = () => {
    const { users: { headerColumns } } = this.state;
    return (
      <th>
        {headerColumns.map(col => (
          <td key={col.label._text}>{col.label._text}</td>
        ))}
        <td>Total Hours</td>
      </th>
    );
  };

  renderTableRows = () => {
    const { users: { rows } } = this.state;
    return rows.map((row, index) => {
      let computedTotal;
      return (
      <tr key={index}>
        {row.col.map((value, index) => {
          // compute time total from row data
          return (
            <td key={index}>{value}</td>
            );
          })}
          <td>{computedTotal}</td>
      </tr>
    )});
  };

  render() {
    return (
      <table>
        <thead>
          <tr>{this.renderTableHeader()}</tr>
        </thead>
        <tbody>
          {this.renderTableRows()}
        </tbody>
      </table>
    );
  }
}