Я новичок в React/Redux и не уверен, что я не делаю что-то неправильно.Второе действие Redux @@ INIT очищает состояние хранилища, которое уже было изменено другим действием.
У меня есть компонент, который вызывает AJAX-вызов на componentDidMount
для извлечения данных с сервера для рендеринга.
Проблема заключается в том, что Redux отправляет два действия @INIT
, и часто второй отправляется после того, как я уже получил ответ от сервера. Он поставляется с пустым (начальным) состоянием, которое передается компоненту реквизита, и в результате я получаю пустой экран.
Пожалуйста, этот журнал производится с помощью редуктора:
я уже нашел, что наличие два @@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);
Как я уже сказал, я не могу воспроизвести этот вопрос сейчас. Я попытаюсь сделать некоторый синтетический пример, чтобы воспроизвести это позже, когда у меня будет больше времени.
Я не уверен, понимаю ваш смысл. Положите ваш редуктор, а запас и компонент будет лучше. –
Дело в том, что когда второе '' '@ @ INIT'' действие обрабатывается редуктором, оно приходит с пустым (начальным?) Состоянием и переопределяет состояние, ранее установленное, когда действие' 'LISTINGS_FOUND'' было уменьшено. В результате компонент перераспределяет пустой список данных. Как я уже сказал, я не могу воспроизвести этот вопрос сейчас. Я попытаюсь сделать некоторый синтетический пример, чтобы воспроизвести это позже, когда у меня будет больше времени. –
Yup, если вы сделаете пример, пожалуйста, дайте мне знать, спасибо. –