Render Method, Meteor React

2019-08-19 14:28发布

问题:

After following the getting started tutorial on the meteor website i stopped around the item "2.4 Create App component", first install:

meteor add http

The app purpose is to visualize in differently the lottery api data of the state of New York.

import React, { Component } from 'react';
import { HTTP } from 'meteor/http';

var apiUrl = 'https://data.ny.gov/api/views/dg63-4siq/rows.json';

export default class App extends Component {

  numbers() {
    HTTP.get(apiUrl, {}, function(err, res){
        if(err){
            console.log('ERROR @ CALL');
        } else {
            console.log(res);
            return res.data.data.slice(-50).map((result, index) => 
            <li key={ result[0] }>{`${result[8]} - ${result[9]}`}</li>
            );
        }
    });
  }

  render() {
    return (
      <div className="container">
        <header>
          <h1>Numbers</h1>
        </header>
        <ul>
          { this.numbers() }
        </ul>
      </div>
    );
  }
}

the object from the http call shows up on the console but not on the DOM

回答1:

I don't think its a good idea to call the functions that makes an API call in the render function as it will be called everytime the component renders, a better place will be to have it in the componentDidMount function and save the result in state. If you want the call to repeat, do it in setInterval function like

export default class App extends Component {
  state = {data: []}
  componentDidMount() {
    var comp = [...this.state.comp]
    this.interval = setInterval(()=> {
      HTTP.get(apiUrl, {}, function(err, res){
        if(err){
            console.log('ERROR @ CALL');
        } else {
            console.log(res);
            this.setState({data: res.data.data.slice(-50)})

        }
        }.bind(this)); 
     }, 2000)

  }
  componentWillUnmount() {
       clearInterval(this.interval)
  }
  render() {
    return (
      <div className="container">
        <header>
          <h1>Numbers</h1>
        </header>
        <ul>
          {this.state.data.map((result, index) => 
             <li key={ result[0] }>{`${result[8]} - ${result[9]}`}</li>
            ); }
        </ul>
      </div>
    );
  }
}


回答2:

Final code.

import React, { Component } from 'react';
import { HTTP } from 'meteor/http';

var apiUrl = 'https://data.ny.gov/api/views/dg63-4siq/rows.json';

export default class App extends Component {
  constructor(props){
      super(props);
      this.state = { data : [] }; 
  }
  componentDidMount(){
      var self = this;
          HTTP.get(apiUrl, {}, function(err, res){
              if(err){
                  console.log('ERROR @ CALL');
                  } else {
                      self.setState((state, props) => ({
                          data : res.data.data.slice(-50)
                          }));
                      console.log("state equals response");
                  }
          });
  }

  render() {
    return (
      <div className="container">
        <header>
          <h1>Numbers</h1>
        </header>
        <ul>
          {this.state.data.map((result) => 
             <li key={ result[0] }>{`${result[8]} - ${result[9].split(' ')}`}</li>
            )}
        </ul>
      </div>
    );
  }
}