2017-02-01 20 views
1

Я пытаюсь использовать jp-интерфейс json-сервера (json-server --watch db.json), чтобы заполнить состояние хранилища потоков. Я вызываю функцию хранилища из родительского компонента componentWillMount для загрузки данных с помощью Axios.Проблема с заполнением состояния через axios

Я смотрел на следующие учебники для справки: http://mediatemple.net/blog/tips/loading-and-using-external-data-in-react/ https://www.toptal.com/react/tips-and-practices и другие.

Вот JSON данные я втягивая:

[ 
    { 
    "complete": "false", 
    "edit": "false", 
    "id": "uuid()", 
    "text": "Go Shopping" 
    }, 
    { 
    "complete": "false", 
    "edit": "false", 
    "id": "uuid()", 
    "text": "Pay Water Bill" 
    } 
] 

db.json сутью https://gist.github.com/WebRuin/548f6073ca533016503d34c36116b8de

Вот отрывок из Flux магазина я звоню:

import { EventEmitter } from 'events' 
import dispatcher from '../dispatcher' 
import axios from 'axios' 

import uuid from 'uuid4' 

class TodoStore extends EventEmitter { 
    constructor() { 
    super() 
    this.state = { 
     todos: [], 
     showCompletedTodos: true, 
     showIncompletedTodos: true 
    } 

    this.deleteTodo = this.deleteTodo.bind(this) 
    this.toggleTodo = this.toggleTodo.bind(this) 
    this.toggleShowCompletedTodos = this.toggleShowCompletedTodos.bind(this) 
    this.toggleShowIncompletedTodos = this.toggleShowIncompletedTodos.bind(this) 
    } 
... 

fetchUserState() { 
    let th = this 
    console.log(th) 
    this.serverRequest = 
     axios.get('http://localhost:3000/todos') 
     .then(function(result) { 
      console.log(result.data) 
      th.state.todos = result.data 
     }) 
    } 

} 

const todoStore = new TodoStore 
dispatcher.register(todoStore.handleActions.bind(todoStore)) 

export default todoStore 

Gist от полного файла: https://gist.github.com/WebRuin/efbbf4296c566f6eb58cc6d641bee4ba

Запись в консоли показывает мне, что запрос axios выполняется с данными, которые я хочу, и журнал this показывает, что заполняется this.state.todos, но реактивный плагин Chrome не отображает данные, и, следовательно, приложение не отображает данные.

Что я делаю неправильно?

+0

Вместо "th.state.todos = result.data", попробуйте "th.setState ({todos: result.data})" –

+0

Очень хороший вопрос. – prosti

ответ

2

Энди прав, кроме конструктора, мы всегда должны использовать setState(), который работает асинхронно при настройке состояния.


От here: 1 и 2


Однако, это верно для общей React. В Flux мы должны забыть метод setState и просто работать с магазинами. Это сообщение из статьи.

Я создал одно изображение для моей навигации по Flux, это может вам помочь.

enter image description here


Как правило, вы должны загрузить данные с помощью Аксиос, а не через componentWillMount(), но вы можете использовать Flux действия потока для этого. Но все же вы можете использовать componentWillMount(), чтобы создать действие.

+0

Это добавляет большой перспективы. Спасибо, все еще не уверен, как использовать this.setState из магазина, созданного с помощью EventEmiter. – Tithos

+0

Git hub it. Должны быть примеры @Tithos – prosti

+0

https://github.com/WebRuin/flux-todo – Tithos

1

Не изменять объект состояния напрямую. Всегда используйте setState().

+0

'this.setState' можно вызвать из' EventEmitter'. Я столкнулся с этим прежде. В моем ограниченном опыте 'this.setState' можно вызывать только из' React.Component 'или' React.creatClass ' – Tithos

+0

'this.setState' не может вызываться из' EventEmitter' Я имею в виду – Tithos

+0

. Ваш код изменяет состояние внутри 'fetchUserState ', который находится на классе компонентов –