2016-12-10 3 views
0

Вызов AJAX возвращает данные, но как назначить его переменной класса, чтобы я мог использовать ее в другом методе? Вот мой код (это reactjs компонент):Как назначить значение, возвращаемое вызовом jQuery AJAX переменной класса?

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> 
     ); 
    } 
} 

Как вы можете видеть, что я задаю его this.potions но render() метода, список пуст.

+0

вы уверены, что данные извлекаются быть правильно? – mattias

+0

Вы должны использовать «состояние» для реагирующих компонентов. – Hosar

+0

@ Matías Я попытался вывести его в консоли несколько раз, «данные» содержат извлеченное значение. – adredx

ответ

1

this.potions, вероятно, обновлен, но ваш компонент не перерисовывается с новыми данными. В React вы можете использовать state и setState, чтобы легко обновлять внутренние данные компонента. Вот код (упрощенно):

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 (e.g. 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>

+0

Не работает. Я обновил свой код выше, чтобы применить ваше решение. Не повезло. – adredx

+0

Вы уверены, что обновили каждый бит? 'this.state.potions' вместо' this.potions' везде. Настроить состояние в конструкторе. Какая ошибка? –

+0

Да только что обновил его. Ошибка: 'Uncaught TypeError: this.state.potions.map не является функцией'. По-видимому, он все еще не получает назначение. – adredx

1

Вы должны обработать случай, когда данные пуст

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> 
    ); 
    } 
} 
+0

@adredx это решило вашу проблему? – mattias

Смежные вопросы