React.js:使用 Fetch API 和对象数组中的道具加载 JSON 数据
Posted
技术标签:
【中文标题】React.js:使用 Fetch API 和对象数组中的道具加载 JSON 数据【英文标题】:React.js: loading JSON data with Fetch API and props from object array 【发布时间】:2016-09-26 15:12:14 【问题描述】:完全是 react.js 的新手,在完成教程和阅读文档之后,我仍然在使用 js fetch 从 JSON 文件加载我的数据以及从对象数组设置属性方面遇到一些问题。我也不确定我是否在我的事件处理程序中正确访问了 DOM 属性。我一定错过了一些相当简单的东西。
供参考,here's my code with the rest of the project 和 here's what it's supposed to look like.
ETA:我从文档中不知道 babel 浏览器已被弃用,因此决定只使用带有 ES5 语法的直接 javascript 而不是 JSX。下面更新了代码,但它仍然没有呈现标记。
var CanvasAnimation = React.createClass(
getInitialState: function()
return data: [];
,
loadData: function()
/*
fetch("data.json")
.then(function(response)
return response.json
.then(function(json)
this.setState(data: json);
.bind(this))
.bind(this));
*/
const data = [
id: "stalkerOne", width: 225, height: 434, spriteSheetURL: 'spriteSheets/stalkerone.jpg', rows: 5, columns: 5, totalFrames: 24 ,
id: "stalkerTwo", width: 175, height: 432, spriteSheetURL: 'spriteSheets/stalkertwo.jpg', rows: 6, columns: 5, totalFrames: 26 ,
id: "stalkerThree", width: 251, height: 432, spriteSheetURL: 'spriteSheets/stalkerthree.jpg', rows: 6, columns: 5, totalFrames: 28
];
,
componentDidMount: function()
this.loadData();
,
componentDidUpdate: function()
function animation(json)
return json.map(function(data)
return(
new CanvasSprite(
document.getElementById(data.id),
data.width,
data.height,
data.spriteSheetURL,
data.rows,
data.columns,
data.totalFrames)
);
);
;
this.setState(animaton: animation(this.state.data));
,
handleInteraction: function(event, index)
var offsetY = event.clientY - event.node.getBoundingClientRect().top;
var relY = offsetY/this.state.data.height;
this.props.animation[index].setFrame(relY);
,
render: function()
var canvases = this.state.data.map(function(data, index)
return (
React.createElement('canvas',
id = data.id,
width = data.width,
height = data.height,
style = 'border:5px solid white',
onMouseOver= this.handleInteraction(event, index))
);
);
return(
React.createElement('div', canvases)
);
);
ReactDOM.render(
React.createElement(CanvasAnimation, null),
document.getElementById('content')
);
【问题讨论】:
您没有在问题中说明问题所在。 虽然this.setState(data: json, animation());
此处缺少一个键,但您似乎在此处有语法错误?
问题是状态和道具似乎都没有实际设置,并且标记没有呈现。你是说需要预定义密钥(在这种情况下为data
)吗?我没有在示例中看到这样做,也没有在文档中引用。
不,我的意思是你在一个对象内部有函数animation()
,没有一个不是合法javascript代码的键..你的意思是 data: json, canvas: animation()
。仔细检查后,您的 animation
函数不会返回任何内容
setState(function(previousState, currentProps) ...),我想你提到的代码是这样的。即使这种风格,函数 setState 仍然会改变 this.state 的结果函数作为参数。
【参考方案1】:
您的代码中有大量语法错误,我已为您修复。
const Component = React;
const render = ReactDOM;
class CanvasAnimation extends Component
state =
data: []
;
loadData()
function animation(json)
return json.map(function(data)
return (
new CanvasSprite(
document.getElementById(data.id),
data.width,
data.height,
data.spriteSheetURL,
data.rows,
data.columns,
data.totalFrames
)
);
);
fetch("data.json")
.then(response => response.json())
.then(json =>
console.log(json);
this.setState(
data: json,
animation: animation(json)
);
);
componentDidMount()
this.loadData();
handleInteraction(e)
var offsetY = e.clientY - e.node.getBoundingClientRect().top;
var relY = offsetY/this.state.data.height;
this.props.animation.setFrame(relY);
render()
var canvases = this.state.data.map(function(data)
return (
<canvas
id=data.id
width=data.width
height=data.height
style=border: '5px white'
onMouseOver=this.handleInteraction
/>
);
);
return (
<div>canvases</div>
);
render(
<CanvasAnimation />,
content
);
我不知道你的 API 的响应,所以我不确定是否还有其他需要修复。
我注意到的一些问题:
可能你的缩进是错误的,因为你有带有双 return
语句的函数。我建议你在你的 IDE 中启用 ESLint 来捕捉这些错误。
你还没有理解setState
是如何工作的,你不能这样做:
this.setState(
foo: 'bar',
baa: myFn(this.state.foo)
);
否则,myFn
中的 this.state.foo
将引用它的旧值,而不是您现在设置的新值。
你必须这样做this.setState(foo: 'bar', () => this.setState(baa: myFn(this.state.foo))
,但是,最好像我在上面修复的代码中那样做。
【讨论】:
问题是我使用了function animation() this.state.data.map()
而不是function animation(json) json.map()
,这更有意义。但这应该只影响道具,而不是状态。我在画布周围设置了边框,这样我就可以判断它们是否至少在渲染,而不管设置的道具如何,而它们不是。 It's not rendering.
你有很多语法错误,不仅仅是动画功能的问题。用 linter 修复所有这些,然后您的页面可能会呈现。
我刚刚粘贴了您的代码。您为回答此问题而编写的代码未呈现。
抱歉,SO 不是您要求编写代码并得到它的地方。我给了你提示和答案来帮助你让你的代码工作。就是这样。
我没有要求任何人为我重写我的代码,但你做到了。您通过重写所有不起作用的代码来回答这个问题,所以如果由于很多语法错误而没有呈现和抛出错误,那么它们就是您的语法错误。这不是问题的答案……只是不同的代码不起作用。所以我想现在我可以选择继续调试我的还是切换到调试你的了?【参考方案2】:
好的...Here's the working project. 得到了@gumingfeng 和@hkal 的帮助。
经验教训:
-
React 文档已经过时了。
Straight JS 与 JSX 真的不比 imo 差。
更正了 Fetch 中的一些语法错误。
为了在构造函数中传递 DOM 引用, 数据加载后需要实例化对象数组。
但是,在
componentDidUpdate()
内调用 setState()
会触发无限循环,因此必须直接且独立于状态设置对象数组。
从数组创建 DOM 元素时,React 不会自动将事件处理程序分配给特定元素。换句话说,它必须传递数组索引,以便可以用来访问它在数组中的值。
哇,我想就是这样。希望这对其他人有帮助。
最后我想说的是,在没有 JSX 的情况下试试 React。真的没那么糟糕:)
const Component = React;
const render = ReactDOM;
class CanvasAnimation extends Component
constructor()
super();
this.state =
data: []
;
;
componentDidMount()
fetch("data.json")
.then( (response) =>
return response.json() )
.then( (json) =>
this.setState(data: json);
);
;
componentDidUpdate()
function animation(json)
return json.map( (data) =>
return(
new CanvasSprite(
document.getElementById(data.id),
data.width,
data.height,
data.spriteSheetURL,
data.rows,
data.columns,
data.totalFrames)
);
);
;
//this.setState(animation: animation(this.state.data)); //causes infinite loop
this.animation = animation(this.state.data);
;
handleInteraction(event, index)
var offsetY = event.clientY - document.getElementById(this.state.data[index].id).getBoundingClientRect().top;
var relY = offsetY/this.state.data[index].height;
this.animation[index].setFrame(relY);
;
render()
var canvases = this.state.data.map( (data, index) =>
return (
React.createElement('canvas',
id : data.id,
width : data.width,
height : data.height,
//style : border: '5px solid white',
onMouseMove : (event) => this.handleInteraction(event, index)
)
);
);
return(
React.createElement('div', null, ...canvases)
);
;
;
render(
React.createElement(CanvasAnimation, null),
document.getElementById('content')
);
【讨论】:
这是对我帮助最大的答案。直接从 componentDidMount() 调用 fetch 解决了未定义的this
挫折以上是关于React.js:使用 Fetch API 和对象数组中的道具加载 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章
Fetch API 无法加载“.php”本地文件 - React JS + PHP
如何使用 React.js 中的 Fetch API 将数据发布到数据库