Я столкнулся с довольно странной проблемой с моим приложением ReactJS x Redux, которую я никогда раньше не видел, и мне трудно разобраться.
В моем компоненте ReactJS я подключаю функцию создателя действий, которая использует redux-thunk
для выполнения асинхронных вызовов перед отправкой на редуктор, используя функцию connect()
из react-redux
+ нотацию объекта mapDispatchToProps
. Это выглядит так:
const mapStateToProps = (state) => ({
...state.single_pano
});
const mapDispatchToProps = {
loadPano
};
export default connect(mapStateToProps, mapDispatchToProps)(PanoView);
Ради простоты, скажем, создатель действия loadPano
выглядит примерно так:
export const loadPano = (id) => {
console.log('Action creator called.');
return async (dispatch) => {
console.log('Dispatch function called.');
const doc = await db.doc('/path/to/doc/'+id).get();
dispatch({
type: 'LOAD_ACTION',
payload: doc
});
}
}
Здесь все становится странно:
В моей функции жизненного цикла componentDidMount()
я выполняю вызов this.props.loadPano(panoID)
, который работает точно так же, как и ожидалось (вызываются оба console.log()
вызова в создателе действий, возвращается async
/ await
и действие направляется на редуктор).
Позже мне нужно снова вызвать this.props.loadPano(panoID)
в функции жизненного цикла компонента componentWillReceiveProps()
, так как параметр URL изменен, а некоторые данные необходимо получить и перезагрузить. ОДНАКО, в этот раз происходит то, что вызывается создатель действия (loadPano
), но никогда не вызывается функция диспетчеризации redux-thunk
(return (dispatch) => { ... }
). Я могу сказать, что это так, потому что первый console.log()
вызывается, но второй никогда не регистрируется на консоли.
Другие, немного необычные вещи, которые я делаю, могут быть связаны, но до сих пор я не смог подтвердить ничего из этого:
- Компонент
PanoView
использует метод жизненного цикла shouldComponentUpdate()
для управления отображением DOM.
- Я немного хакерский / не лучший специалист, использующий переменную вне состояния
PanoView
компонента для хранения стороннего библиотечного объекта, который изменяет DOM напрямую через DOM ref
, и не может действительно будет использоваться должным образом в сочетании с ReactJS. Однако я считаю, что это изолировано, и не могу понять, как это будет мешать Redux / Thunk. Тем более, что функция отправки срабатывает правильно с первого раза.
Соответствующие зависимости + версии (установлены через yarn
):
"firebase": "^5.2.0",
"photo-sphere-viewer": "^3.4.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
Запрошенные обновления:
Моя componentWillReceiveProps
функция lifecylce для компонента PanoView
выглядит следующим образом:
componentWillReceiveProps(newProps) {
// Pano received
const oldPanoID = this.props.match.params.panoID;
const newPanoID = newProps.match.params.panoID;
if (oldPanoID !== newPanoID) {
loadPano(newPanoID);
}
}