#javascript #reactjs #redux #react-redux
#javascript #reactjs #redux #реагировать-redux
Вопрос:
Я работал над Next.js приложение с этими зависимостями:
"react": "^16.9.0",
"react-redux": "^5.0.7",
"redux": "^4.0.4",
Одним из моих действий redux, которое создает stepsNameThatMustBeShown
(свойство состояния redux), является:
export const setInitialSteps = () => {
//.....
// some codes that creates the stepsNameThatMustBeShown array
//....
return {
type: ActionTypes.SET_QUICK_RESUME_GENERATOR_MODAL_INITIAL_STEPS,
data: stepsNameThatMustBeShown
}
};
И я использовал этот фрагмент в двух разных местах моего приложения, в компоненте класса и функциональном компоненте.
<button onClick = {
async () => {
await this.props.setInitialSteps();
if (this.props.stepsNameThatMustBeShown.length > 1) {
this.props.setCurrentStep(this.props.stepsNameThatMustBeShown[0]);
this.props.setQuickResumeDisplayStatus(true);
this.props.setUnUpdatedStepsName([...this.props.stepsNameThatMustBeShown]);
}
}}>
Open
</button>
//....
//...
const mapStateToProps = (state) => {
return {
stepsNameThatMustBeShown: state.quickResumeGeneratorModal.stepsNameThatMustBeShown,
};
};
function mapDispatchToProps(dispatch) {
return {
setQuickResumeDisplayStatus: bindActionCreators(setQuickResumeDisplayStatus, dispatch),
setInitialSteps: bindActionCreators(setInitialSteps, dispatch),
setCurrentStep: bindActionCreators(setCurrentStep, dispatch),
setUnUpdatedStepsName: bindActionCreators(setUnUpdatedStepsName, dispatch),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(resultTest);
Очевидно, что я не использовал this.props
в функциональном компоненте. Все эти функции в фрагменте кода являются действиями redux. Во фрагменте кода я обновил свойство состояния redux и использовал его сразу после его обновления.
В компоненте класса ключевые слова async и await работают так, как мы ожидали, но в функциональном компоненте ключевое слово await работает некорректно. Я прочитал некоторые связанные вопросы, которые существуют в этом сообществе, но ни один из них не смог помочь мне решить мою проблему.
Комментарии:
1. Основываясь на приведенном выше коде, я не вижу ни одного варианта использования
async await
, возможно, вы слишком много думаете. Попробуйте удалитьasync await
и посмотреть, решит ли это. Вы вызываете this.props.setInitialSteps();` который будет выполняться синхронно и возвращать и выполнять следующую строку в вашем обработчике кликов.2. функция @Rikin setInitialSteps инициализирует stepsNameThatMustBeShown prop, поэтому мне нужно ее инициализировать, а затем использовать как часть условия оператора if, поэтому я должен использовать функцию await .
3. является ли эта функция
stepsNameThatMustBeShown
асинхронной? если это так, то используйтеawait
при вызове выполнения, опять же, нет необходимости в await в вашем обработчике кликов.4. Это не функция, это свойство состояния redux.
5.
setInitialSteps
является вашим создателем действия (на основе того, что вы показываете). Он не делает ничего, кроме возврата действия с типом действия и вашей полезной нагрузкойdata
. Вызывая его в своем функциональном компоненте, вы возвращаете только этот объект, вы ничего с ним не делаете. В вашем компоненте класса вы связываете ту функцию,bindActionCreators
которая выполняетdispatch
для вас, таким образом, она работает. Опять же, ничего общего сasync
await
still на основе того, что вы показали выше.
Ответ №1:
Вам необходимо использовать react-redux 7.1 или более поздней версии для использования const dispatch = useDispatch()
в вашем функциональном компоненте, а затем вызвать dispatch()
обработчик onClick.
В вашем функциональном компоненте используйте:
const dispatch = useDispatch()
и тогда ваш обработчик будет выглядеть следующим образом:
<button onClick = {
async () => {
const action = this.props.setInitialSteps(); // <======
dispatch(action); // <=====
if (this.props.stepsNameThatMustBeShown.length > 1) {
this.props.setCurrentStep(this.props.stepsNameThatMustBeShown[0]);
this.props.setQuickResumeDisplayStatus(true);
this.props.setUnUpdatedStepsName([...this.props.stepsNameThatMustBeShown]);
}
}}>
Open
</button>
Опять же, все async
то, что у вас есть, здесь не нужно в вашем случае использования.