在 React 中,如何在 HTML 表格中显示来自 API 的数据?

IT技术 javascript reactjs
2021-05-02 11:07:33

我正在尝试显示来自我的示例 API 的数据。目前我可以遍历数组并显示所有标题,例如:

EventTitle1
EventTitle2
EventTitle3
...

这是我的代码:

class App extends React.Component {
constructor() {
   super();
   this.state = {
      data: []
   }
}
 
componentDidMount() {
 var th = this;
 this.serverRequest = axios.get(this.props.source)
 .then(function(event) { 
     th.setState({
         data: event.data
     });
 })
}

componentWillUnmount() {
  this.serverRequest.abort();
}
 
render() {
 var titles = []
 this.state.data.forEach(item => {
    titles.push(<h3 className=”events”>{item.title[0].value}</h3> );
 })
 return (
    <div className=”container”>
      <div className=”row”>
         <div className=”col-md-6 col-md-offset-5">
             <h1 className=”title”>All Events</h1>
             {titles} 
         </div>
      </div>
    </div>
  );
 } 
}

ReactDOM.render(
   <App source=”http://localhost:8888/example/api/events" />, 
   document.getElementById(‘container’)
);

我如何创建一个 HTML 表格,以仅显示表格内来自 API(以及后来的其他数据)的五个最新事件标题?

例如:

return (
    <table>
      <tr>
        <th>Event title</th>
        <th>Event location</th> 
      </tr>
      <tr>
        <td>First event title {titles[0]} ?? </td> 
        <td>San Fran</td>
      </tr>
      <tr>
        <td>Second event title {titles[1]} ??</td> 
        <td>London</td> 
      </tr>
    </table>
);
3个回答

创建一个数组<tr>并将其添加到表中。

class App extends React.Component {
constructor() {
   super();
   this.state = {
      data: []
   }
}
 
componentDidMount() {
 var th = this;
 this.serverRequest = axios.get(this.props.source)
 .then(function(event) { 
     th.setState({
         data: event.data
     });
 })
}

componentWillUnmount() {
  this.serverRequest.abort();
}
 
render() {
 const contents = this.state.data.forEach(item => {
      // change the title and location key based on your API
      return <tr>
        <td>{item.title}</td> 
        <td>{item.location}</td>
      </tr>
 })
 return (
    <div className="container">
      <div className="row">
         <div className="col-md-6 col-md-offset-5">
             <h1 className="title">All Events</h1>
             <table>
              <tr>
                <th>Event title</th>
                <th>Event location</th> 
              </tr>
                {contents}
            </table>
         </div>
      </div>
    </div>
  );
 } 
}

ReactDOM.render(
   <App source="http://localhost:8888/example/api/events" />, 
   document.getElementById("container")
);

您可以简单地使用slice运算符获取数组的前 5 个元素,然后直接使用map.

也不需要使用titles数组,您只需将代码片段内联到 jsx 中即可。

代码的重要部分是:

<table>
    {data.slice(0,5).map(event => (<tr>
        <td>{event.title}</td>
        <td>{event.location}</td>
    </tr>))}
</table>

这是完整的示例:

class App extends React.Component {
constructor() {
   super();
   this.state = {
      data: []
   }
}
 
componentDidMount() {
 var th = this;
 this.serverRequest = axios.get(this.props.source)
 .then(function(event) { 
     th.setState({
         data: event.data
     });
 })
}

componentWillUnmount() {
  this.serverRequest.abort();
}
 
render() {
 return (
    <div className=”container”>
      <div className=”row”>
         <div className=”col-md-6 col-md-offset-5">
            <h1 className=”title”>All Events</h1>
            <table>
               <tr>
                  <th>Event title</th>
                  <th>Event location</th> 
               </tr>
               {this.state.data.slice(0,5).map(event => (<tr>
                  <td>{event.title}</td>
                  <td>{event.location}</td>
               </tr>))}
            </table>
         </div>
      </div>
    </div>
  );
 } 
}

ReactDOM.render(
   <App source=”http://localhost:8888/example/api/events" />, 
   document.getElementById(‘container’)
);

我只是不会在上面的例子中那样编码。

  1. 我不会使用设置变量来this 提醒我很多人所做的 angularjs 的旧时代 var vm = this (vm 用于视图模型)
  2. 需要使用带有箭头函数的现代 javascript 并使用map而不是forEach

    示例如下:

    class App extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
               data: []
            }
        }
    
        componentDidMount() {
    
           axios.get(this.props.source)
               .then((event) => { 
                   this.setState({
                       data: event.data
                   });
           })
        }
    
    
    render() {
         const yourData = this.state.data.map(item => (
         // notice array so no return here , ( ) instead of { } 
        // notice also map instead of forEach creates a closure - map is preferred
        <tr>
            <td>{item.title}</td> 
            <td>{item.location}</td>
        </tr>
    })
    return (
       <div className=”container”>
            <div className=”row”>
                 <div className=”col-md-6 col-md-offset-5">
                     <h1 className=”title”>All Events</h1>
                      <table>
                        <tr>
                           <th>Event title</th>
                            <th>Event location</th> 
                        </tr>
                       {yourData}
                   </table>
                 </div>
              </div>
          </div>
         );
       } 
    }
    
     ReactDOM.render(
       <App source=”http://localhost:8888/example/api/events" />, 
           document.getElementById(‘container’)
     );
    
     // above obviously works and old way of doing things, and that is for a div id of containter
    // I would setup an api to append to and use the componentDidMount() {... }  
    // then -->   export default App;