简体   繁体   中英

How to assign a value returned by jQuery AJAX call to a class variable?

The AJAX call returns data but how do I assign it to a class variable so that I can use it in another method? Here's my code(this is reactjs component):

import React from 'react';
import jQuery from 'jquery';
import ListPotions from './list_potions';

export default class Potions extends React.Component {
    constructor(props) {
        super(props);
        this.state = {potions: []};
        this.fetchPotions = this.fetchPotions.bind(this);
        this.objToStrMap = this.objToStrMap.bind(this);
    }

    componentDidMount() {
        this.fetchPotions();
    }

    fetchPotions() {
        jQuery.ajax({
            url: this.props.endPoint,
            dataType: 'json',
            cache: false,
            headers: {
                "Authorization": btoa('mixOfRandomPotions')
            },
            success: function(data) {
                let potions = this.objToStrMap(data);
                this.setState({ potions });
            }.bind(this),
            error: function(xhr, status, err) {
                console.error(this.props.endPoint, status,        
                err.toString());
            }.bind(this)
        });
    }

    objToStrMap(obj) {
        let strMap = new Map();
        for (let k of Object.keys(obj)) {
            strMap.set(k, obj[k]);
        }
        return strMap;
    }

    render(){
        console.log(this.potions);
        return (
            <div className="{this.props.className}">
                <ul>
                    {this.state.potions.map((potion) => <ListPotions key="{potion.id}" potion={potion} /> )}
                </ul>
            </div>
        );
    } 
}

As you can see I'm assigning it to this.potions but in render() method, the list is empty.

this.potions is probably updated, but your component is not being re-rendered with the new data. In React, you can use state and setState to easily update the internal data of a component. Here's your code (simplified):

 class Potions extends React.Component { constructor(props) { super(props); this.state = { potions: [] }; this.fetchPotions = this.fetchPotions.bind(this); } componentDidMount() { this.fetchPotions(); } fetchPotions() { // not a network request, I just set some sample data. your request would go here. const potions = [{ id: 1, name: 'first' }, { id: 2, name: 'second' }]; // instead of overwriting a variable (eg this.potions), we update the state // put this into your network request callback! this.setState({ potions }); } render() { console.log(this.state.potions); return ( <div className="{this.props.className}"> <ul> {this.state.potions.map((potion) => <li key={potion.id}>{potion.name}</li> )} </ul> </div> ); } } ReactDOM.render(<Potions/>, document.getElementById('View')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="View"></div> 

You should handle the case when the data is empty

render() {
    const { potions, className } = this.state;

    if (!potions) {
      return (<p>Loading...</p>);
    } else {
      return (
          <div className="{className}">
              <ul>
                  {potions.map(potion => <li key={potion.id}>{potion.name}</li> )}
              </ul>
          </div>
      );
    }
}

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