简体   繁体   中英

basic reactjs, how to get REST data and render it

I have a basic rect component and I already figured out how to get data from a protected rest api, however I am not sure how to render it in the component and how to call that function, or in which lifecycle I should call the function.

import React, { Component } from 'react';
import LayoutContentWrapper from '../components/utility/layoutWrapper';
import LayoutContent from '../components/utility/layoutContent';
var q = require('q');

var Adal = require('../adal-webapi/adal-request');

function getValues() {
    var deferred = q.defer();
    Adal.adalRequest({
      url: 'https://abc.azurewebsites.net/api/values'
    }).then(function(data) {
      console.log(data);
    }, function(err) {
      deferred.reject(err);
    });
    return deferred.promise;
  }

export default class extends Component {



  render() {
    return (
      <LayoutContentWrapper style={{ height: '100vh' }}>
        <LayoutContent>
          <h1>Test Page</h1>
        </LayoutContent>
      </LayoutContentWrapper>
    );
  }
}

something like this...

export default class extends React.Component {
  constructor(props) {
    super(props);
    // initialize myData to prevent render from running map on undefined
    this.state = {myData: []};
  }

  // use componentDidMount lifecycle method to call function
  componentDidMount() {
    // call your function here, and on promise execute `setState` callback
    getValues()
      .then(data => {
        this.setState({myData: data})
      }
  }

  render() {
    // create a list
    const items = this.state.myData.map((datum) => {
      return <LayoutContent>
        <h1>{datum}</h1>
      </LayoutContent>
   });

    // return with the list
    return (
      <LayoutContentWrapper style={{ height: '100vh' }}>
        {items}
      </LayoutContentWrapper>
    );
  }
}

The lifecycle method you choose to fetch the data in will largely depend on whether or not you need to update the data at any point and re-render, or whether that data depends on any props passed to the component.

Your example looks as though it is a one time API call that doesn't depend on any props, so placing it in the constructor would be valid.

I would move the getValues code to within the class, and do something like this. Note: I've used async/await, but you could use promise callbacks if you prefer.

export default class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: []
        }
        this.fetchData();
    }

    async fetchData() {
        try {
            const data = await this.getValues();
            !this.isCancelled && this.setState({ data });
        } catch(error) {
            // Handle accordingly
        }
    }

    getValues() { 
        // Your API calling code
    }

    componentWillUnmount() {
        this.isCancelled = true;
    }

    render() {
        const { data } = this.state;
        return (
            <ul>
                {data && data.map(item => (
                    <li>{item.name}</li>
                ))}
            </ul>
        );
    }
}

If you needed to fetch the data again at any point, you might use one of the other lifecycle hooks to listen for prop changes, and call the fetchData method again.

Note the inclusion of a failsafe for the component un-mounting before the async call has finished, preventing React from throwing an error about setting state in an unmounted component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM