У меня проблема, когда я пытаюсь использовать состояние Redux, чтобы остановить выполнение некоторого опроса, используя состояние в условном выражении if
. Я просмотрел сообщения SO и блогов, но, к сожалению, никто не занимался моей проблемой. Я проверил, правильно ли я использую mapStateToProps, я постоянно обновляю состояние и использую Redux-Thunk для асинхронных действий. Некоторые сообщения, на которые я смотрел:
Мне любезно помогли с методологией опроса в этом посте: Включение асинхронных действий, обещание.then() и рекурсивный setTimeout, избегая при этом «отложенного антипаттерна» , но я хотел использовать избыточное состояние в качестве единственного источника правды, но, возможно, это невозможно в моем случае использования.
У меня естьобрезать код для удобства чтения актуальной проблемы, чтобы включить только соответствующие аспекты, поскольку у меня есть большой объем кода. Я рад опубликовать все это, но хотел, чтобы вопрос был как можно более скудным.
Loader.js
import { connect } from 'react-redux';
import { delay } from '../../shared/utility'
import * as actions from '../../store/actions/index';
const Loader = (props) => {
const pollDatabase = (jobId, pollFunction) => {
return delay(5000)
.then(pollFunction(jobId))
.catch(err => console.log("Failed in pollDatabase function. Error: ", err))
};
const pollUntilComplete = (jobId, pollFunction) => {
return pollDatabase(jobId, pollFunction)
.then(res => {
console.log(props.loadJobCompletionStatus) // <- always null
if (!props.loadJobCompletionStatus) { <-- This is always null which is the initial state in reducer
return pollUntilComplete(jobId, pollFunction);
}
})
.catch(err=>console.log("Failed in pollUntilComplete. Error: ", err));
};
const uploadHandler = () => {
...
const transferPromise = apiCall1() // Names changed to reduce code
.then(res=> {
return axios.post(api2url, res.data.id);
})
.then(postResponse=> {
return axios.put(api3url, file)
.then(()=>{
return instance.post(api3url, postResponse.data)
})
})
transferDataPromise.then((res) => {
return pollUntilComplete(res.data.job_id,
props.checkLoadTaskStatus)
})
.then(res => console.log("Task complete: ", res))
.catch(err => console.log("An error occurred: ", err))
}
return ( ...); //
const mapStateToProps = state => {
return {
datasets: state.datasets,
loadJobCompletionStatus: state.loadJobCompletionStatus,
loadJobErrorStatus: state.loadJobErrorStatus,
loadJobIsPolling: state.loadJobPollingFirestore
}
}
const mapDispatchToProps = dispatch => {
return {
checkLoadTaskStatus: (jobId) =>
dispatch(actions.loadTaskStatusInit(jobId))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(DataLoader);
delay.js
export const delay = (millis) => {
return new Promise((resolve) => setTimeout(resolve, millis));
}
actions.js
...
export const loadTaskStatusInit = (jobId) => {
return dispatch => {
dispatch(loadTaskStatusStart()); //
const docRef = firestore.collection('coll').doc(jobId)
return docRef.get()
.then(jobData=>{
const completionStatus = jobData.data().complete;
const errorStatus = jobData.data().error;
dispatch(loadTaskStatusSuccess(completionStatus, errorStatus))
},
error => {
dispatch(loadTaskStatusFail(error));
})
};
}
Кажется, что когда я консольный журнал, значение props.loadJobCompletionStatus
всегда пустокоторый является начальным состоянием в моем редукторе. Используя инструменты Redux-dev, я вижу, что состояние действительно обновляется, и все действия происходят так, как я ожидал.
Сначала я поместил props.loadJobCompletionStatus
в качестве аргумента pollDatabase
и подумал, что, возможно, создал замыкание, и поэтому я удалил аргументы в определении функции, чтобы функция получала результаты из«верхние» уровни области видимости, надеясь, что это принесет последнее состояние Redux. Я не уверен, почему я остался с устаревшей версией государства. Это приводит к тому, что мой оператор if выполняется всегда, и поэтому у меня бесконечный опрос базы данных.
Кто-нибудь может указать, что может быть причиной этого?
Спасибо