我正在尝试获取React组件的数据并将其设置为处于状态的嵌套对象:
import React from 'react';
import './App.css';
import XLSX from "xlsx";
class App extends React.Component {
constructor(props){
super(props);
this.state = {
isLoading:false,
cards:{}
}
}
componentDidMount(){
this.setState({isLoading:true});
/* convert xlsx to JSON */
fetch("../data/Cards_v0.1.xlsx")
.then((d)=> d.arrayBuffer()).then((d)=>{
const data = new Uint8Array(d);
const workbook = XLSX.read(data, {type:"buffer"});
const sheet = workbook.Sheets["Deck"];
const cardsJSON = XLSX.utils.sheet_to_json(sheet,{range:1});
let cards = {};
for(let i=0; i<cardsJSON.length; i++){
for(let j=0; j<cardsJSON.length; j++){
cards[cardsJSON[i].Name] = cardsJSON[i];
}
}
this.setState({cards:cards, isLoading:false});
});
}
render() {
if(this.state.isLoading){
return <div>Loading</div>;
}
return (
<div>
{ this.state.cards.Single.Name }
</div>
);
}
}
export default App;
React devtools显示对象处于状态,其中 cards> Single> Name 为“ Single”,但是{this.state.cards.Single.Name}
抛出 TypeError:无法读取属性'Name'未定义。
最让我感到困惑的是,{this.state.cards.Single}
抛出了对象作为React子对象无效(找到:键为{Name,Type,Rarity,Text,Money}的对象)。如果要渲染子级集合,请改用数组。
因此,Name
键没有被调用时被找到,但是当我调用它时,该对象变成了未定义状态?
非常困惑。任何帮助表示赞赏!
答案 0 :(得分:1)
反应不知道如何显示对象,因此,{this.state.cards.Single}
将抛出Objects are not valid as a React child
。
设置React状态还有一些奇怪的选择。由于该组件始终会在装载时获取数据,因此将isLoading
缺省设置为true,然后在成功获取响应时将其设置为false更为有意义。
我不知道您的cardsJSON
的结构,但是下面的示例显示了两种显示嵌套JSON的方式。
JSON.stringify(obj, replacer, spaces)
this.state.cards
破坏对象属性(如果这些属性中的任何一个也是嵌套对象,那么它们也需要被破坏!),然后在表,列表中显示所有被破坏的数据等工作示例:https://codesandbox.io/s/km3wwvqqzv
Example.js
import React, { Component, Fragment } from "react";
import DisplayCode from "./displayCode";
import DisplayList from "./displayList";
export default class Example extends Component {
state = {
isLoading: true,
cards: {}
};
componentDidMount = () => {
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(json => this.setState({ cards: json, isLoading: false }));
};
render = () =>
this.state.isLoading ? (
<div>Loading</div>
) : (
<Fragment>
<DisplayCode cards={this.state.cards} />
<DisplayList cards={this.state.cards} />
</Fragment>
);
}
displayCode.js
import React, { Fragment } from "react";
export default ({ cards }) => (
<Fragment>
<h3>Display JSON as code:</h3>
<pre style={{ height: 300, overflowY: "auto" }}>
<code>{JSON.stringify(cards, null, 4)}</code>
</pre>
</Fragment>
);
displayList.js
import map from "lodash/map";
import React, { Fragment } from "react";
export default ({ cards }) => (
<Fragment>
<h3 style={{ marginTop: 30 }}>Display JSON as list:</h3>
<ul style={{ height: 300, overflowY: "auto" }}>
{map(
cards,
({
id,
name,
username,
email,
address: {
street,
suite,
city,
zipcode,
geo: { lat, lng }
}
}) => (
<li key={id}>
<strong>id:</strong> {id}
<ul>
<li>
<strong>Username:</strong> {username}
</li>
<li>
<strong>Name:</strong> {name}
</li>
<li>
<strong>Email:</strong> {email}
</li>
<li>
<strong>Street: </strong>
{street}
</li>
<li>
<strong>Suite: </strong>
{suite}
</li>
<li>
<strong>City: </strong>
{city}
</li>
<li>
<strong>Zipcode: </strong>
{zipcode}
</li>
<li>
<strong>Lat: </strong>
{lat}
</li>
<li>
<strong>Lng: </strong>
{lng}
</li>
</ul>
</li>
)
)}
</ul>
</Fragment>
);