ReactJS-在AJAX调用之后,应该使用哪个组件生命周期方法创建表并填充数据

ReactJS-在AJAX调用之后,应该使用哪个组件生命周期方法创建表并填充数据,reactjs,Reactjs,我试图弄清楚在AJAX调用发生并检索数据之后,如何用数据显示和填充一个表 用户从AppointmentHome开始,它有一个日期选择器,在那里他们可以选择想要检索的约会日期。选择日期并单击搜索后,将调用getAppointmentData(),并检索数据 目前,我正在将数据检索到getAppointData()回调中的var appointmentArray中,然后在回调中调用CreateTableRows(),以便在检索数据之后而不是之前调用它 现在,我很难弄清楚如何在AppointmentL

我试图弄清楚在AJAX调用发生并检索数据之后,如何用数据显示和填充一个表

用户从AppointmentHome开始,它有一个日期选择器,在那里他们可以选择想要检索的约会日期。选择日期并单击搜索后,将调用getAppointmentData(),并检索数据

目前,我正在将数据检索到getAppointData()回调中的var appointmentArray中,然后在回调中调用CreateTableRows(),以便在检索数据之后而不是之前调用它

现在,我很难弄清楚如何在AppointmentList的呈现中获取CreateTableRows()的输出,以便它与表的其余部分一起填充。我相信我可能需要将一些代码移动到一些生命周期方法中,但我一直在思考如何从一个组件移动到下一个组件,而不会搞乱数据的检索

var appointmentArray = null;
var table;

function getAppointmentData(){
  window.getAppointments(date, 'callback');
}

window.callback = function(objects){
  appointmentArray = objects;
  table = createTableRows();
}

function createTableRows(){
  var output = "<tbody>";
  for (var i = 0; i < 1; i++){
    output += "<tr><th scope='row'>"+appointmentArray[i]+ "</th></tr>";
  }
  output += "</tbody>";
  return output;
}


export class AppointmentList extends React.Component {
  constructor(props){
    super(props);
  }

  render(){
    return(
      <div className = "appointment-table">
        <table className="table table-hover">
          <thead>
            <tr>
              <th scope="col">Patient Name</th>
              <th scope="col">Time</th>
              <th scope="col">Duration</th>
              <th scope="col">Provider</th>
              <th scope="col">Appointment Status</th>
            </tr>
          </thead>
        </table>
      </div>
    );
  }
}

export class AppointmentHome extends React.Component {
  constructor(props){
    super(props);

    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(){
    getAppointmentData();
  }

  render(){
    return(
      <div>
        <h3> Appointment Search </h3>
        <div className = 'search'>
          <h3> Date </h3>
          <Calendar />
          <div className = 'searchButton'>
            <Link to="appointments">
                <RaisedButton label="Search" onClick = {this.handleClick}/>
            </Link>
          </div>
        </div>
      </div>
    );
  }
}
var appointmentArray=null;
var表;
函数getAppointmentData(){
获取约会(日期,“回调”);
}
window.callback=函数(对象){
appointmentArray=对象;
table=createTableRows();
}
函数createTableRows(){
var输出=”;
对于(变量i=0;i<1;i++){
输出+=“”+appointmentArray[i]+“”;
}
输出+=“”;
返回输出;
}
导出类任命列表扩展React.Component{
建造师(道具){
超级(道具);
}
render(){
返回(
患者姓名
时间
期间
供应商
预约状态
);
}
}
导出类AppointmentHome扩展React.Component{
建造师(道具){
超级(道具);
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
getAppointmentData();
}
render(){
返回(
预约查询
日期
);
}
}

Facebook推荐的生命周期方法是
componentDidMount
。引述:

componentDidMount()
在安装组件后立即调用。需要DOM节点的初始化应该在这里进行如果需要从远程端点加载数据,这是实例化网络请求的好地方。

请注意,装载后加载数据意味着在渲染方法中,必须注意数据尚未加载的情况。通常,这是通过一个条件语句来完成的,该语句在没有数据时呈现微调器或类似的内容,在数据可用时呈现实际数据

约会示例

虽然这(希望)回答了您关于使用哪种生命周期方法的问题,但实际上与您的情况无关,因为您是在用户单击按钮后加载数据的。在本例中,您将在click handler方法中执行此操作,并提供一个设置组件状态的回调函数

例如,我建议在
AppointmentHome
组件中添加一个状态,在加载约会数据后将其添加到状态,并将该数据作为道具提供给
AppointmentList
组件

像这样:

class AppointmentHome extends React.Component {
  constructor(props) {
    super(props);

    this.handleClick = this.handleClick.bind(this);
    this.state = {
      appointments: null,
      isLoading: false
    };
  }

  handleClick() {
    this.setState({ appointments: null, isLoading: true });
    getAppointmentData(appointments =>
      this.setState({ appointments, isLoading: false })
    );
  }

  render() {
    const { appointments, isLoading } = this.state;
    return (
      <div>
        <div className="search">
          <button onClick={this.handleClick}>Search</button>
        </div>
        {isLoading && <div>Please wait...</div>}
        {appointments && <AppointmentList appointments={appointments} />}
      </div>
    );
  }
}
正如您所看到的,不需要像您在代码中尝试做的那样将任何HTML代码连接到字符串中,所有这些都由组件优雅地处理:

  • 约会数组是组件的一个属性
  • 数组映射为为每个约会创建一个表行
加载JSONP数据

您正在使用JSONP从API加载数据,可能是为了规避跨源资源共享限制

这很好,但是您需要能够将任意回调函数传递给执行JSONP魔术的函数。如果您在代码示例中使用全局变量,它将不起作用,因为
AppointmentApp
很难与之连接

您可以使用以下建议的解决方案:

将所有内容放在一起

看看我创建的这个代码沙盒,它显示了正在运行的代码:


在AppointmentHome或AppointmentList中调用componentDidMount()吗?如果你能举个例子,那就太好了!关于你的问题,实际棘手的部分是你正在使用一个全局回调,大概是因为你正在调用的API正在使用JSONP,对吗?那么,我的回答有用吗?如果是,请接受
class AppointmentList extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const { appointments } = this.props;
    return (
      <div className="appointment-table">
        <table className="table table-hover">
          <thead>
            <tr>
              <th scope="col">Patient Name</th>
              <th scope="col">Time</th>
              <th scope="col">Duration</th>
              <th scope="col">Provider</th>
              <th scope="col">Appointment Status</th>
            </tr>
          </thead>
          <tbody>
            {appointments.map((appointment, i) => (
              <tr key={`appointment${i}`}>
                <td scope="col">{appointment.patientName}</td>
                <td scope="col">{appointment.time}</td>
                <td scope="col">{appointment.duration}</td>
                <td scope="col">{appointment.provider}</td>
                <td scope="col">{appointment.appointmentStatus}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}
function jsonp(url, callback) {
    var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
    window[callbackName] = function(data) {
        delete window[callbackName];
        document.body.removeChild(script);
        callback(data);
    };

    var script = document.createElement('script');
    script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
    document.body.appendChild(script);
}