2017-01-05 4 views
0

У меня возникли проблемы при попытке получить исходные данные для моего приложения из api.Реакция диспетчерского действия ничего не делает

Моя проблема в том, что после console.log(url) в действии ничего не происходит. Я вижу URL-адрес в консоли, но остальная часть кода в getInitialRuns(), похоже, не выполняется, по крайней мере, не так, как я ожидаю. Я не получаю сообщений об ошибках.

При использовании Postman я могу успешно получить ответ от этой конечной точки API, поэтому API должен быть в порядке.

У меня есть действия, которые выглядят так:

function requestRuns(){ 
    console.log('request') 
    return { 
    type: 'getInitialRuns' 
    } 
} 

export function getInitialRuns(){ 
    var url = 'http://localhost:32118/api/Runs'; 
    console.log(url); 
    return dispatch => { 
    dispatch(requestRuns()) 

    return fetch(url) 
     .then(response => response.json().then(body => ({response, body}))) 
     .then(({response, body}) => { 
     if(!response.ok){ 
      console.log('fail') 
     } 
     else{ 
      console.log('success') 
     } 
     }) 
    } 

компонент, который вызывает действие выглядит следующим образом:

class RunList extends Component{ 
    constructor(props) { 
    super(props) 
    } 

    componentWillMount(){ 
    getInitialRuns() 
    } 

    render() { 
    const {runs, isFetching, error} = this.props 

    return (
     <ul className="run-list"> 
       {runs.map((run) => 
        <Run key={run.Id} id={run.Id} date={run.DateString} day={run.Day} distance={run.Distance} duration={run.DurationString} avgpace={run.AvgPaceString} calories={run.Calories}/> 
      )} 
      </ul> 
    ) 
    } 
} 

RunList.propTypes = { 
    isFetching: PropTypes.bool.isRequired, 
    runs: PropTypes.instanceOf(Immutable.List), 
    error: PropTypes.object 
} 

function mapStateToProps(state) { 
return{ 
    runs: state.runs, 
    isFetching: state.isFetching, 
    error: state.error 
} 
} 

export default connect(mapStateToProps)(RunList) 

Мой магазин настроен так:

import { createStore, applyMiddleware } from 'redux'; 
import {composeWithDevTools} from 'redux-devtools-extension'; 
import runs from './reducers/runs'; 
import thunk from 'redux-thunk'; 

export default createStore(runs,composeWithDevTools(applyMiddleware(thunk))) 

И это мои редукторы

import Immutable from 'immutable' 

let initialState = { 
    runs: Immutable.List([]), 
    isFetching: false, 
    error: undefined 
}; 

export default (state = initialState, action) => { 
    switch(action.type) { 
    case 'addRun': 
     return state.unshift(action.run) 
    case 'deleteRun': 
     return Object.assign({}, state, { 
     runs: state.runs.filter((run) => run.Id !== action.id) 
     }) 
    case 'getInitialRuns': 
     console.log('initial') 
     return Object.assign({}, state, { 
     isFetching: true 
     }) 
    case 'getInitialRunsSuccess': 
    console.log('success') 
     return Object.assign({}, state, { 
     isFetching: false, 
     runs: action.runs 
     }) 
    case 'getInitialRunsFailure': 
     return Object.assign({}, state, { 
     isFetching: false, 
     error: action.error 
     }) 
    default: 
     return state 
    } 
} 

ответ

2

Для того чтобы послать действие на Redux, вы должны предоставить функцию mapDispatchToProps t o connect. От redux docs:

(..) Вы можете определить функцию с именем mapDispatchToProps(), который принимает метод отправки() и возвращает обратный вызов реквизит, который вы хотите ввести в презентационный компонент

const mapDispatchToProps = (dispatch) => { 
    return { 
    onTodoClick: (id) => { 
     dispatch(toggleTodo(id)) 
    } 
    } 
} 

Я вижу, что вы используете некоторые продвинутые библиотеки, такие как Immutablejs. Я предлагаю , вы начинаете с чтения the awesome redux documentation, поскольку он будет вам шаг за шагом. И пока вы не знакомы с базовыми концепциями сокращения, избегайте любой другой библиотеки.

Вот некоторые заметки я надеюсь, будут полезны для вас: (они взяты из redux docs)

Примечания

  • Объект Действие, которое полезную нагрузку информации, передачи данных из ваше приложение в ваш магазин.Он имеет такой вид:

    вар ADD_TODO = { Тип: ADD_TODO, текст: «Создайте свой первый Redux приложение» }

  • Рекомендуется назвать вам типы действий в верхнем регистре, как ADD_TODO.
  • dispatch принимает объект действия (см. Пример выше).
  • Рекомендуется использовать создателей действий, которые являются функциями, возвращающими объект действия. Это делает их легко проверяемыми и переносимыми
  • Создатели действий обычно называются в нижнем регистре: addTodo().

Я надеюсь, что это помогает немного

+0

MapDispatchToProps - это то, что мне нужно. Я также рассмотрю другие лучшие практики. Спасибо! – spersson

0

Вы должны вернуть новое состояние, если вы хотите, чтобы Redux заметил изменение состояния.

Ваши дела редуктор должен выглядеть примерно так:

return { 
    ...previousState, 
    newValues 
} 

'addRun'

return state.unshift(action.run) 

должен быть

return {...state, runs: state.run.unshift(action.run) } 
+0

Спасибо, я буду помнить об этом. Я не вижу, как это предотвращает вызов моего API? Я что-то упускаю? – spersson

0

Функция getInitialRuns возвращает функцию, поэтому при вызове она ничего возвращаемой функции не выполняет. Btw Я не уверен, что это будет полезно для вашего приложения.

Редукторы синхронны, поэтому, если вам нужно сделать что-либо асинхронное, вам понадобится промежуточное программное обеспечение, например, сокращающее или понижающее.

потока должно быть:

Государство -> Просмотров -> Actions -> Middleware -> Actions -> Переходники -> Государство и обратно Просмотров

Пожалуйста, посмотрите на документы на http://redux.js.org/docs/advanced/AsyncActions.html

Кроме того, вы можете наслаждаться отличные бесплатные курсы по Умник:

https://egghead.io/courses/getting-started-with-redux

https://egghead.io/courses/building-react-applications-with-idiomatic-redux

На github вы найдете много материала на курсах.

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