学习反应,虽然我了解组件的生命周期,但我不明白,虽然我的JSON调用成功但它不会呈现我最初提取的项目列表。当我向列表添加新项目时,它会进行渲染,但这需要我单击编辑按钮并添加新元素。
var InterBox = React.createClass({
getInitialState: function(){
return {
"content" : [],
"editing" : false,
"pulled" : false
}
},
componentDidMount: function(){
var url = "http://jsonplaceholder.typicode.com/posts";
var tempdata = this.state.content;
$.getJSON(url, function(data){
for (var i = 0; i < data.length; i++) {
var element = data[i];
tempdata.push(element.body);
console.log(tempdata);
}
});
this.setState({"content":tempdata});
this.forceUpdate();
},
addContent: function(e){
var currentContent = this.state.content;
currentContent.push(this.refs.content.value);
this.refs.content.value = "";
this.setState({"content" : currentContent, "editing" : false});
this.render();
},
changeMode: function(e){
this.setState({"editing": true});
this.render();
},
render: function(){
if (this.state.editing)
return(
<div>
<h1>{this.props.title}</h1>
<input type="text" ref="content"/>
<button onClick={this.addContent}>Add</button>
</div>
);
else{
var items = [];
for (var i = 0; i < this.state.content.length; i++) {
var element = this.state.content[i];
items.push(<li>{element}</li>);
}
return(
<div>
<h1>{this.props.title}</h1>
<button onClick={this.changeMode}>Edit</button>
<ul>
{items}
</ul>
</div>
);
}
}
});
ReactDOM.render(
<InterBox title="Hello"></InterBox>,
document.getElementById('main')
);
这是初始输出
这应该是什么样的
答案 0 :(得分:5)
1。)由于 $。getJSON func是 async ,因此您应该等待响应,然后在回调中调用setState。< / p>
let {content} = this.state;
$.getJSON(url,data=>{
let result = data.map(e=>e.body);
this.setState({content:[...content, ...result]});
});
2。) 您不需要 forceUpdate()和render(),因为setState为您调用渲染组件。
3。) 你不应该通过push()来改变你的状态。它会导致问题和错误。相反,你可以使用spread operator或concat等
//concat returns new array
let {content} = this.state;
this.setState({content:content.concat(result)});
//spread operator
let {content} = this.state;
this.setState({content:[...content, ...result]});
4。) 如果你不想在回调中使用arrow func ,你应该使用bind(this),否则你将在回调中使用未定义 for setState
let {content} = this.state;
$.getJSON(url,function(data){
let result = data.map(e=>e.body);
this.setState({content:content.concat(result)});
}.bind(this));
答案 1 :(得分:0)
不要手动调用渲染函数,即应该通过反应调用。 你在AJAX呼叫响应之外设置了setState。
var InterBox = React.createClass({
getInitialState: function(){
return {
"content" : [],
"editing" : false,
"pulled" : false
}
},
componentDidMount: function(){
var url = "http://jsonplaceholder.typicode.com/posts";
var tempdata = this.state.content;
$.getJSON(url, function(data){
for (var i = 0; i < data.length; i++) {
var element = data[i];
tempdata.push(element.body);
console.log(tempdata);
}
this.setState({"content":tempdata});
});
},
addContent: function(e){
var currentContent = this.state.content;
currentContent.push(this.refs.content.value);
this.refs.content.value = "";
this.setState({"content" : currentContent, "editing" : false});
},
changeMode: function(e){
this.setState({"editing": true});
},
render: function(){
if (this.state.editing)
return(
<div>
<h1>{this.props.title}</h1>
<input type="text" ref="content"/>
<button onClick={this.addContent}>Add</button>
</div>
);
else{
var items = [];
for (var i = 0; i < this.state.content.length; i++) {
var element = this.state.content[i];
items.push(<li>{element}</li>);
}
return(
<div>
<h1>{this.props.title}</h1>
<button onClick={this.changeMode}>Edit</button>
<ul>
{items}
</ul>
</div>
);
}
}
});
ReactDOM.render(
<InterBox title="Hello"></InterBox>,
document.getElementById('main')
);
答案 2 :(得分:0)
无需this.forceUpdate()
或this.render()
来电。屏幕将刷新,即在render()
之后由React调用this.setState()
。
未显示数据的原因是您在致电this.setState()
后立即致电$.getJSON()
,而不是getJSON()
成功回调。
这应该有效:
$.getJSON(url, function(data){
for (var i = 0; i < data.length; i++) {
var element = data[i];
tempdata.push(element.body);
console.log(tempdata);
this.setState({"content":tempdata});
}
});