2016-10-19 3 views
0

Я пытаюсь получить некоторые данные из api с помощью Redux. Мой код выглядит следующим образом:Redux fetch data from api

Действие:

// Import libraries 
import axios from 'axios'; 

// Import types 
import { 
    GET_ALL_PICKS 
} from './types'; 

export const getAllPicks = ({ token }) => { 
    const getPicks = (dispatch) => { 
    axios({ 
     method: 'get', 
     url: 'http://myapi/', 
     headers: { 
     Authorization: `Bearer ${token}` 
     } 
    }) 
    .then((response) => { 
     console.log(response.data); // First log here returns data just fine 
     dispatch({ 
     type: GET_ALL_PICKS, 
     payload: response.data 
     }); 
    }) 
    .catch((error) => { 
     console.log(error); 
    }); 
    }; 

    return getPicks; 
}; 

Разбавление:

// Import types 
import { 
    GET_ALL_PICKS 
} from '../actions/types'; 

// Set Initial State 
const INITIAL_STATE = { 
    allPicks: {}, 
    loading: false, 
    error: '' 
}; 

// Make pick reducers 
export default (state = INITIAL_STATE, action) => { 
    switch (action.type) { 
    case GET_ALL_PICKS: 
     return { ...state, allPicks: action.payload }; // Logging action.payload here returns data just fine 
    default: 
     return state; 
    } 
}; 

Компонент:

// Import Libraries 
import React, { Component } from 'react'; 
import { Text } from 'react-native'; 
import { connect } from 'react-redux'; 
import { 
    getAllPicks 
} from '../actions/picks'; 

// Make Component 
class HomeScreen extends Component { 
    // Fetch Data 
    componentWillMount() { 
    const { token } = this.props; 

    this.props.getAllPicks({ token }); 
    } 

    // Test response 
    componentDidMount() { 
    console.log(this.props.allPicks); // This log returns empty object, why?! 
    } 

    render() { 
    return (
     <Text>Test</Text> 
    ); 
    } 
} 

const mapStateToProps = ({ auth, picks }) => { 
    const { token } = auth; 
    const { allPicks } = picks; 

    return { 
    token, 
    allPicks 
    }; 
}; 

export default connect(mapStateToProps, { getAllPicks })(HomeScreen); 

Когда я запустить приложение я вижу данные в действии console.log и если я запустил console.log(action.payload) в редукторе, я вижу данные просто отлично, но в компоненте I см. пустой массив, который предполагает, что я не правильно подключаю данные в моем редукторе? Вот снимок экрана из бревен:

enter image description here

Я также попытался это в моем редукторе после некоторого Googling:

return Object.assign({}, state, { 
    allPicks: action.payload 
    }); 

но я опять получил тот же результат. Может ли кто-нибудь объяснить мне, что я делаю неправильно?

ответ

3

Вы путаете жизненный цикл компонента и жизненный цикл API.

На практике, что происходит это:

  • componentWillMount
  • getAllPicks
  • componentDidMount (в этот момент, то API не вернулся, кирки пустые)
  • [... подождите, пока API вернется]
  • затем API возвращается с данными, но слишком поздно

Что вам нужно сделать, так это проверить состояние «picks» в функции render(), которая будет обновляться каждый раз, когда ваше состояние изменяется (что происходит, когда API возвращается), благодаря функции connect().

Вы также можете проверить правильность обновления киев, используя componentWillUpdate, а не componentDidMount, который снова не имеет ничего общего с обновляемыми реквизитами.