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 se
Ok... Here's the working project. Got some help from @gumingfeng and @hkal.
Lessons learned:
setState()
inside componentDidUpdate()
triggers an infinite loop so had to set the object array directly and independently from state.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')
);
You 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
inside myFn
will refer to the old value of it, and not to the new one that you are setting right now.
You'd have to do this.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.