2017-02-16 12 views
-1

Я новичок в React/Redux и не уверен, что я не делаю что-то неправильно.Второе действие Redux @@ INIT очищает состояние хранилища, которое уже было изменено другим действием.

У меня есть компонент, который вызывает AJAX-вызов на componentDidMount для извлечения данных с сервера для рендеринга.

Проблема заключается в том, что Redux отправляет два действия @INIT, и часто второй отправляется после того, как я уже получил ответ от сервера. Он поставляется с пустым (начальным) состоянием, которое передается компоненту реквизита, и в результате я получаю пустой экран.

Пожалуйста, этот журнал производится с помощью редуктора: enter image description here

я уже нашел, что наличие два @@INIT действия является ожидаемым поведением, первым необходимо для проверки редукторов и второй один является актуальной инициализацией (проверьте обсуждение here).

Вопрос в том, как я могу решить эту проблему надлежащим образом. Это состояние гонки или я что-то не так? Благодаря!

Обновление Интересно, что это определенно относится к производительности моего ноутбука. Сервер также работает в моей локальной среде. Чтобы позволить мне продолжить разработку, пока я жду ответа, я временно поставил setTimeout с задержкой 100 мс в componentDidMount. Теперь я прокомментировал это и не могу воспроизвести проблему.

Update Добавление части моего кода

магазина

import { createStore, applyMiddleware, compose } from 'redux'; 
import thunk from 'redux-thunk'; 

import reducers from './reducers'; 

const middleware = window.devToolsExtension 
    ? compose(
     applyMiddleware(thunk), 
     window.devToolsExtension() 
    ) 
    : applyMiddleware(thunk); 

const store = createStore(reducers, middleware); 

export default store; 

Reducer (ничего особенного, просто использовали его, чтобы войти в действие, потому что браузер расширение Redux показывает только один @@INIT действия)

import * as types from '../actions/types'; 

const initialState = { 
    listings: [] 
}; 

export default function(state = initialState, action) { 
    console.log(action, state); 
    switch (action.type) { 
     case types.LISTINGS_FOUND: 
      return { listings: action.payload }; 

     default: return state; 
    } 
}; 

Компонент

import React from 'react'; 
import { connect } from 'react-redux'; 

import { search as searchListings } from '../../actions/listing-actions' 
import View from './View' 

class Container extends React.Component { 
    componentDidMount() { 
     if (this.props.listings.length === 0) { 
      this.props.searchListings(); 
     } 
    } 

    render() { 
     console.log('rendering list', this.props.listings); 
     return (
      <View listings={this.props.listings}/> 
     ); 
    } 
} 

Container.propTypes = { 
    listings: React.PropTypes.arrayOf(React.PropTypes.object).isRequired, 
    searchListings: React.PropTypes.func.isRequired, 
}; 

const mapStateToProps = function(store) { 
    return { 
     listings: store.listingSearch.listings 
    }; 
}; 

export default connect(mapStateToProps, { searchListings })(Container); 

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

+0

Я не уверен, понимаю ваш смысл. Положите ваш редуктор, а запас и компонент будет лучше. –

+0

Дело в том, что когда второе '' '@ @ INIT'' действие обрабатывается редуктором, оно приходит с пустым (начальным?) Состоянием и переопределяет состояние, ранее установленное, когда действие' 'LISTINGS_FOUND'' было уменьшено. В результате компонент перераспределяет пустой список данных. Как я уже сказал, я не могу воспроизвести этот вопрос сейчас. Я попытаюсь сделать некоторый синтетический пример, чтобы воспроизвести это позже, когда у меня будет больше времени. –

+0

Yup, если вы сделаете пример, пожалуйста, дайте мне знать, спасибо. –

ответ

0

Вы должны загрузить компонент componentDidMount(), как рекомендовано в docu. Вы также можете увидеть в этом example от создателя Redux.

+0

Я сделал опечатку. Я имел в виду '' 'componentDidMount'''. Сожалею. –

+0

где вы инициализируете свой магазин? – juancab

+0

'' 'store''' создается непосредственно перед созданием элемента' '' Provider'''. Я импортирую '' 'store''' и' '' router''' и передаю их '' 'Provider''', который передается корневому элементу с' '' 'ReactDom'''. –