admin管理员组文章数量:1173625
Totally new to react.js and after going through the tutorial and reading the docs, I'm still struggling a bit with using js fetch to load my data from a JSON file as well as setting properties from an array of objects. I'm also not certain I'm accessing DOM properties correctly in my event handler. I must be missing something rather straightforward.
For reference, here's my code with the rest of the project and here's what it's supposed to look like.
ETA: I had no idea from the docs that babel browser was deprecated so decided to just use straight Javascript with ES5 syntax instead of JSX. Code updated below, but it's still not rendering the markup.
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')
);
Totally new to react.js and after going through the tutorial and reading the docs, I'm still struggling a bit with using js fetch to load my data from a JSON file as well as setting properties from an array of objects. I'm also not certain I'm accessing DOM properties correctly in my event handler. I must be missing something rather straightforward.
For reference, here's my code with the rest of the project and here's what it's supposed to look like.
ETA: I had no idea from the docs that babel browser was deprecated so decided to just use straight Javascript with ES5 syntax instead of JSX. Code updated below, but it's still not rendering the markup.
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')
);
Share
Improve this question
edited Mar 17, 2022 at 8:37
VLAZ
28.9k9 gold badges62 silver badges82 bronze badges
asked May 28, 2016 at 10:09
Sophia GoldSophia Gold
7511 gold badge8 silver badges18 bronze badges
19
|
Show 14 more comments
2 Answers
Reset to default 24You have tons of syntax errors in your code, I have fixed them for you.
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
);
I don't know the response of your API so I'm not sure if there's other to fix.
Some of the problems I have noticed:
Probably your indentation is wrong, because you had functions with double
return
statements. I suggest you to enable ESLint in your IDE to catch those errors.You have not understood how
setState
works, you can't just do:this.setState({ foo: 'bar', baa: myFn(this.state.foo) });
Otherwise,
this.state.foo
insidemyFn
will refer to the old value of it, and not to the new one that you are setting right now.
You'd have to dothis.setState({foo: 'bar'}, () => this.setState({baa: myFn(this.state.foo)})
, but then, it's better to do as I did in the code I have fixed above.
Ok... Here's the working project. Got some help from @gumingfeng and @hkal.
Lessons learned:
- The React docs are ridiculously outdated.
- Straight JS vs. JSX is really no worse imo.
- Corrected some syntax errors in Fetch.
- Object array needs to be instantiated after data is loaded in order to pass DOM references in the constructors.
- However, calling
setState()
insidecomponentDidUpdate()
triggers an infinite loop so had to set the object array directly and independently from state. - When creating DOM elements from an array, React does not automatically assign the event handler to the particular element. In other words, it must be passed the array index so that can be used to access its values in the arrays.
Whew, I think that's it. Hope this helps others.
And I would just conclude by saying, give React a try without JSX. It's really not that bad :)
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')
);
本文标签: javascriptReactjs loading JSON data with Fetch API and props from object arrayStack Overflow
版权声明:本文标题:javascript - React.js: loading JSON data with Fetch API and props from object array - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1737609395a1998665.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
this.setState({data: json, animation()});
Missing a key here? – azium Commented May 28, 2016 at 15:29data
in this case) needs to be predefined? I don't see this being done in the examples nor referenced in the docs. – Sophia Gold Commented May 28, 2016 at 15:37animation()
inside an object without a key that's not legal javascript code.. did you mean{ data: json, canvas: animation() }
. Upon closer inspection youranimation
function doesn't return anything – azium Commented May 28, 2016 at 15:39