2017-11-04 29 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({待办事项。}); }); }' –