我需要在另一个组件中单击渲染组件,如下所示:
我有DevStatus
组件,它只是两个bootstrap radiobuttons。我有IssuesList
组件是boostrap列表。
因此,当用户点击其中一个单选按钮时,我需要使用IssuesList
单选按钮的closed_issues
数组Closed Issues
数组来呈现open_issues
组件。Open Issues
} {array} for IssuesList
radiobutton)。我是React的新手,但我想我只是要改变组件的状态,它会触发重新渲染,这是正确的吗?
但是,我无法将DevStatus
的状态与closed_issues
上的点击事件相关联。你可以帮我这么做吗?
此外,那些open_issues
和$.getJSON
数组实际上是来自function _getIssues() {
let issues = $.getJSON('https://api.github.com/repos/org_name/project/issues?state=all&filter=all')
.done( (data) => { issues = data } );
return issues;
}
方法的jQuery ajax响应。如何实现此数据获取过程,以便它不会阻止UI线程,并且实际上在收到JSON响应时会呈现?
这就是我要获得JSON的方式:
_getIssues()
所以,我只会得到一个所有问题的数组,之后我需要把它分成两部分。但要做到这一点,我首先需要调用undefined
方法,该方法首先返回undefined
的数组,并在几毫秒之后该数组将成为有效数据。但是,我认为这足以打破app并且React不会呈现class DevStatus extends React.Component {
constructor(props) {
super(props);
this.state = {
issues: [{title: '', html_url: '#', state: 'open'}]
};
this.CLOSED_ISSUE_ID = 'closed_issue_r';
this.OPEN_ISSUE_ID = 'open_issue_r';
}
getIssues(p_url, p_data, cbSuccess) {
console.log('getIssues');
let request = $.ajax({
url: p_url,
method: "GET",
data: p_data
});
request.done(cbSuccess);
request.fail(console.log);
}
componentWillMount() {
let url = 'https://api.github.com/repos/repo/project/issues?state=all&filter=all';
this.getIssues(url, {issues: 'open'}, this.onBackendResponse.bind(this));
}
onBackendResponse(data) {
console.log('onBackendResponse');
this.issues = data;
this.setState({ issues: data });
}
onChangeRadioButton(e) {
console.log('onChangeRadioButton')
console.log(e.target.id);
switch(e.target.id) {
case OPEN_ISSUE_ID:
this.setState({ issues: this.getOpenedIssues(this.issues).bind(this) });
break;
case CLOSED_ISSUE_ID:
this.setState({ issues: this.getClosedIssues(this.issues).bind(this) });
break;
}
}
getClosedIssues(issues) {
console.log('filter closed');
return issues.filter((issue) => { issue.state === 'open' });
}
getOpenedIssues(issues) {
console.log('filter opened');
return issues.filter((issue) => { issue.state === 'closed' });
}
render() {
console.log(this.issues);
return (
<div className="dev-status-page col-centered">
<div className="issues col-centered">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active">
<input type="radio" name="options" id={this.CLOSED_ISSUE_ID}
autoComplete="off" onChange={this.onChangeRadioButton.bind(this)}/> Closed Issues
</label>
<label className="btn btn-primary">
<input type="radio" name="options" id={this.OPEN_ISSUE_ID}
autoComplete="off" onChange={this.onChangeRadioButton.bind(this)} /> Open Issues
</label>
</div>
<IssuesList issues={this.state.issues} />
</div>
</div>
)
}
}
class IssuesList extends React.Component {
constructor(props) {
super(props);
}
render () {
let issues = this.props.issues.map( (item, index) => {
return (
<a key={index} className="list-group-item"
href={item.html_url} target="_blank">
{item.title}
</a>
);
});
return (
<div className="list-group">
{issues}
</div>
);
}
}
IssuesList.propTypes = {
issues: React.PropTypes.array
};
的数组。如果这个假设是正确的,我该如何避免呢?
现在我有了这个:
if (sizeof($video_url)!=0) {
echo 'true';
}
else
{
echo 'false';
}
答案 0 :(得分:1)
回答你的第一个问题:是的改变状态正是你应该做的。使用this.setState更改状态会再次调用render方法。
你可以这样做:
var CLOSED_ISSUE_ID = 'closed_issue_r', OPEN_ISSUE_ID = 'open_issue_r';
var getAsyncDataFromBackend = function(p_url, p_data, cbSuccess){
var request = $.ajax({
url: p_url,
method: "POST",
data: p_data
});
request.done(cbSuccess);
}
//..
getInitialState:function(){
//empty state so App doesnt <quote>break</quote>
return {issue_data:[]}
},
componentWillMount:function(){
//init component with open issues
//will be executed emediately before render.
getAsyncDataFromBackend(url, {issues: 'open'}, this.onBackendResponse);
},
render:function(){
return (
<button id={OPEN_ISSUE_ID} onClick={this.onChangeRadioButton}>opened</button>
<button id={CLOSED_ISSUE_ID} onClick={this.onChangeRadioButton}>closed</button>
<IssueList list={this.state.issue_data} />
)
},
onChangeRadioButton: function(e){
switch(e.target.id){
case OPEN_ISSUE_ID:
getAsyncDataFromBackend(url, {issues: 'open'}, this.onBackendResponse);
break;
case CLOSED_ISSUE_ID:
getAsyncDataFromBackend(url, {issues: 'closed'}, this.onBackendResponse);
break;
}
},
onBackendResponse(data){
this.setState({issue_data: data});
}
//...
在您的方法getAsyncDataFromBackend
中,您很可能会封装一些ajax代码。
因此,您在react组件的render函数中所做的只是调用<IssueList list={this.state.issue_data} />
组件。
我希望这有帮助吗?
EDIT2:我为AJAX和渲染部分做了一些代码示例,使其更加明显。
希望你现在能抓住我。
答案 1 :(得分:1)
最理智的解决方案是在保持反应并且不做助焊剂或状态容器的同时,将数据一直传递到第一个共同父级,然后再次传递给消费组件
使用单选按钮将组件中的回调发送到组件,使用更改从ajax调用的完成回调中触发,然后父级可以更新其状态并使用新数据重新呈现子级。
编辑:随着更新将问题更改为另一个解决方案,这是关于在一个组件中状态/数据更改时如何在兄弟/父项中触发重新渲染。