Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery ReactJS。在另一个组件中单击渲染组件(基于类切换)_Jquery_Ajax_Reactjs - Fatal编程技术网

Jquery ReactJS。在另一个组件中单击渲染组件(基于类切换)

Jquery ReactJS。在另一个组件中单击渲染组件(基于类切换),jquery,ajax,reactjs,Jquery,Ajax,Reactjs,我需要在单击另一个组件时渲染该组件,如下所示: 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

我需要在单击另一个组件时渲染该组件,如下所示:

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});
}
//...
我有
DevStatus
组件,它只是两个引导单选按钮。我有
IssuesList
组件,它是boostrap列表

,

因此,当用户单击其中一个单选按钮时,我需要用另一个数据呈现
IssuesList
组件(
closed\u issues
radiobutton的
array和
open\u issues
radiobutton的
array)。我是个新手,但我想我只需要改变组件的状态,它就会触发重新启动,对吗

但是,我无法将
IssuesList
的状态与
DevStatus
上的click事件链接起来。你能帮我做那件事吗

另外,那些
closed\u问题
open\u问题
数组实际上是来自
$.getJSON
方法的jQuery ajax响应。我如何实现这个数据获取过程,以便它不会阻塞UI线程,并且在接收到JSON响应时实际呈现

下面是我获取JSON的方法:

function _getIssues() {
    let issues = $.getJSON('https://api.github.com/repos/org_name/project/issues?state=all&filter=all')
                  .done( (data) => { issues = data } );
    return issues;
}
所以,我将得到所有问题的一个数组,然后我需要将它分成两部分。但要做到这一点,我首先需要调用
\u getIssues()
方法,该方法首先将返回
未定义的数组,几毫秒后该数组将成为有效数据。但是,我认为这足以破坏应用程序,并且不会导致
数组未定义。如果这个假设是正确的,我如何避免它

更新 现在我有这个:

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
};
类DevStatus扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
问题:[{title:'',html_url:'#',state:'open'}]
};
this.CLOSED_ISSUE_ID='CLOSED_ISSUE_r';
this.OPEN_ISSUE_ID='OPEN_ISSUE_r';
}
获取问题(p_url、p_数据、cbSuccess){
console.log('getIssues');
让请求=$.ajax({
url:p_url,
方法:“获取”,
数据:p_数据
});
请求完成(cbSuccess);
请求失败(console.log);
}
组件willmount(){
让url为空https://api.github.com/repos/repo/project/issues?state=all&filter=all';
this.getIssues(url,{issues:'open'},this.onBackendResponse.bind(this));
}
onBackendResponse(数据){
log('onBackendResponse');
这个问题=数据;
this.setState({issues:data});
}
onChangeRadioButton(e){
console.log('onChangeRadioButton')
console.log(e.target.id);
开关(如target.id){
案件未决问题编号:
this.setState({issues:this.getOpenDissues(this.issues.bind(this)});
打破
案件结案\u问题\u ID:
this.setState({issues:this.getClosedIssues(this.issues.bind(this)});
打破
}
}
getClosedIssues(问题){
console.log(“过滤器关闭”);
返回issues.filter((issue)=>{issue.state==='open'});
}
GetOpenDissues(问题){
console.log(“过滤器已打开”);
返回issues.filter((issue)=>{issue.state==='closed'});
}
render(){
console.log(this.issues);
返回(
已解决问题
公开问题
)
}
}
类IssuesList扩展了React.Component{
建造师(道具){
超级(道具);
}
渲染(){
let issues=this.props.issues.map((项目,索引)=>{
返回(
);
});
返回(
{问题}
);
}
}
IssuesList.propTypes={
问题:React.PropTypes.array
};

回答您的第一个问题:是的,更改状态正是您应该做的。使用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});
}
//...
var CLOSED_ISSUE_ID='CLOSED_ISSUE_r',OPEN_ISSUE_ID='OPEN_ISSUE_r';
var getAsyncDataFromBackend=函数(p_url、p_数据、cbSuccess){
var请求=$.ajax({
url:p_url,
方法:“张贴”,
数据:p_数据
});
请求完成(cbSuccess);
}
//..
getInitialState:函数(){
//空状态,因此应用程序不会中断
返回{issue_data:[]}
},
componentWillMount:function(){
//具有开放问题的init组件
//将在渲染前立即执行。
getAsyncDataFromBackend(url,{issues:'open'},this.onBackendResponse);
},
render:function(){
返回(
开的
关闭
)
},
onChangeRadioButton:功能(e){
开关(如target.id){
案件未决问题编号:
getAsyncDataFromBackend(url,{issues:'open'},this.onBackendResponse);
打破
案件结案\u问题\u ID:
getAsyncDataFromBackend(url,{issues:'closed'},this.onBackendResponse);
打破
}
},
onBackendResponse(数据){
this.setState({issue_data:data});
}
//...
在您的方法
getAsyncDataFromBackend
中,您很可能会封装一些ajax代码

因此,在react组件的渲染函数中所做的一切就是调用
组件

我希望这有帮助

EDIT2:我已经为AJAX和渲染部分做了更多的代码示例,使其更加明显


希望您现在能明白我的意思。

最明智的解决方案是,在不使用通量或状态容器的情况下,将数据一直传递到第一个公共父级,然后再传递到消费组件

使用单选按钮将props中的回调发送到组件,在ajax调用中的done回调中使用更改触发回调,然后父级可以更新其状态,并使用新数据重新呈现子级

编辑:随着更新,问题变为另一个解决方案,这是关于如何在s中触发重新渲染