2017-11-04 28 views
0

我有兩個jsx文件。 TodoAPI.jsx有一個名爲getTodos()的函數,它使用axios從mongodb數據庫中獲取數據,並如測試所示那樣成功完成。這個函數通常由TodoApp.jsx中的某些行調用,顯然整個代碼在getTodos()甚至返回數組之前執行。因此,應該由getTodos()填充的所有數組都保持未定義狀態。通過在TodoApp.jsx中使用這個setTimeout(function(){ console.log(TodoAPI.getTodos()); }, 3000);,我確信我沒有錯,因爲它實際上打印了數組。嘗試通過調用使用axios的函數(異步)來填充數組,並且函數在填充數組之前返回undefined

如何確保getTodos()在代碼的其他部分啓動之前完成?還是有更好的解決方案?

這裏是代碼的相關部分: TodoAPI.jsx:

var $ = require('jquery'); 
import axios from 'axios'; 

module.exports = { 
    setTodos: function (todos) { 
    if ($.isArray(todos)) { 
     localStorage.setItem('todos', JSON.stringify(todos)); 
     return todos; 
    } 
    }, 
    getTodos: function() { 
    let todos = []; 
    axios({ 
     method: 'get', 
     //url:'https://nameless-island-69625.herokuapp.com/todos', 
     url: 'http://localhost:3000/todos', 
     headers:{ 
     'x-auth': localStorage.getItem('x-auth') 
     } 
    }).then(function(response) { 
     todos = $.extend(true, [], response.data.todos); 
     console.log('successful response from todos'); 
    }).then(() => { 
     console.log(todos); 
     return todos; 
    }).catch((e) => { 
     console.log('failed response from todos'); 
     console.log(e); 
    }); 
    // return [{name:'asd'},{name:'qwe'},{name:'fgd'},]; 
    }, 

TodoApp.jsx:

var React = require('react'); 
var uuid = require('node-uuid'); 
var moment = require('moment'); 
const axios = require('axios'); 

var TodoList = require('TodoList'); 
var AddTodo = require('AddTodo'); 
var TodoSearch = require('TodoSearch'); 
var TodoAPI = require('TodoAPI'); 


var TodoApp = React.createClass({ 
    getInitialState: function() { 
    return { 
     showCompleted: false, 
     searchText: '', 
     todos: TodoAPI.getTodos() 
    }; 
    }, 

其餘的代碼可以發現here但我敢肯定,問題出在上面的代碼中。

+0

你有沒有考慮在返回'getTodos東西:)功能({' –

+0

是的,我試過returnin g .then()外,但我得到同樣的問題,只有這次空數組返回而不是未定義。問題在於函數在數據到達之前完成。 –

回答

1

您不能在getInitialState中分配todos狀態,因爲api調用是異步的。相反,請在componentDidMount中設置todos。喜歡的東西:

componentDidMount() { 
    axios.get('http://localhost:3000/todos') 
    .then(res => { 
     this.setState({ todos: res.data.todos }); 
    }); 
} 

如果您希望您的API調用在一個單獨的文件,那麼就一定要return axios(...從功能和componentDidMount做這樣的事情:

componentDidMount() { 
    getTodos().then(todos => { 
    this.setState({ todos }); 
    }); 
} 

在這種情況下,你getTodos函數可能看起來像:

+0

非常感謝。 'VAR TodoApp = React.createClass({ getInitialState:函數(){ 回報{ showCompleted:假的, SEARCHTEXT: '', 待辦事項:我使用componentDidMount()看起來像這樣改變了我的代碼] }; }, componentDidMount:函數(){ TodoAPI.getTodos(),然後(待辦事項=> { 的console.log(待辦事項); this.setState({待辦事項。}); }); }' –