Я работаю над приложением React и использую Redux для хранения состояния. У меня есть следующий код:
category-arrow.component.jsx:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { increaseCategoryRank, decreaseCategoryRank, fetchCategoryRanks } from '../../redux/menu/menu.actions';
import './category-arrows.styles.scss';
class CategoryArrows extends Component {
render() {
const { category } = this.props;
const categoryClicked = true;
return (
<div className="arrows-container">
<div className="up-arrow" onClick={
() => {
this.props.increaseCategoryRank(category, categoryClicked)
this.props.fetchCategoryRanks(this.props.menu);
}}></div>
<div className="category-rank">
<p>{category.rank}</p>
</div>
<div className="down-arrow" onClick={
() => {
this.props.decreaseCategoryRank(category, categoryClicked)
this.props.fetchCategoryRanks(this.props.menu);
}}></div>
</div>
)
}
}
const mapStateToProps = state => ({
menu: state.menu
})
export default connect(mapStateToProps, { increaseCategoryRank, decreaseCategoryRank, fetchCategoryRanks } )(CategoryArrows);
menu.actions. js:
import { apiUrl, apiConfig } from '../../util/api';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK, FETCH_CATEGORY_RANKS } from './menu.types';
export const decreaseCategoryRank = (category, categoryClicked) => dispatch => {
dispatch({ type: DECREASE_CATEGORY_RANK, category, categoryClicked })
}
export const increaseCategoryRank = (category, categoryClicked) => dispatch => {
dispatch({ type: INCREASE_CATEGORY_RANK, category, categoryClicked })
}
export const fetchCategoryRanks = menu => async dispatch => {
console.log("Printing menu (fetch category ranks)");
console.log(menu);
menu.map(async (category) => {
console.log("PRINTING CATEGORY");
console.log(category.name);
console.log(category.rank);
const options = {
...apiConfig(),
method: 'PUT',
body: JSON.stringify(category)
}
const response = await fetch(`${apiUrl}/category/${category._id}`, options)
let data = await response.json()
if (response.ok) {
console.log("It got sent")
} else {
alert(data.error)
}
});
dispatch({ type: FETCH_CATEGORY_RANKS, menu });
}
menu.types. js:
export const INCREASE_CATEGORY_RANK = "INCREASE_CATEGORY_RANK";
export const DECREASE_CATEGORY_RANK = "DECREASE_CATEGORY_RANK";
export const FETCH_CATEGORY_RANKS = "FETCH_CATEGORY_RANKS";
menu.reducer. js:
// import INITIAL_STATE from './menu.data';
import { INCREASE_CATEGORY_RANK, DECREASE_CATEGORY_RANK, FETCH_CATEGORY_RANKS } from './menu.types';
const INITIAL_STATE = []
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case INCREASE_CATEGORY_RANK: {
console.log("Went into increase category rank");
if(action.categoryClicked === false) {
return state;
}
const menuArray = [...state];
var index = menuArray.map(category => category._id).indexOf(action.category._id);
//if it's the first element in array it won't move up
if(index === 0) {
return state;
} else {
const temp = menuArray[index];
menuArray[index] = menuArray[index - 1];
menuArray[index - 1] = temp;
var newrank = 0;
menuArray.forEach(category => {
category.rank = newrank++;
});
return menuArray;
}
}
case DECREASE_CATEGORY_RANK: {
console.log("Went into decrease category rank");
if(action.categoryClicked === false) {
return state;
}
const menuArray = [...state];
console.log(menuArray);
var index = menuArray.map(category => category._id).indexOf(action.category._id);
//if it's the last element in the array, it won't move down
if(index === menuArray.length - 1) {
return state;
} else {
const temp = menuArray[index];
menuArray[index] = menuArray[index + 1];
menuArray[index + 1] = temp;
var newrank = 0;
menuArray.forEach(category => {
category.rank = newrank++;
});
return menuArray;
}
}
case FETCH_CATEGORY_RANKS:
return state;
default:
return state;
}
}
В моем компоненте CategoryArrows при нажатии на элемент up-arrow
div отправляется действие increaseCategoryRank
, за которым следует действие fetchCategoryRanks
. При нажатии down-arrow
div отправляется действие decreaseCategoryRank
, за которым следует действие fetchCategoryRanks
.
Действия increaseCategoryRank
и decreaseCategoryRank
изменяют ранги категорий, находящихся в состоянии Redux. Действие fetchCategoryRanks
выводит массив меню из состояния и отправляет данные об измененных категориях на сервер с помощью запросов на выборку.
Одна проблема, с которой я сталкиваюсь в моем приложении, заключается в том, что increaseCategoryRank
или decreaseCategoryRank
действия могут быть отправлены снова (путем нажатия на стрелку div) до того, как все запросы на выборку будут отправлены в fetchCategoryRanks
. Это приводит к тому, что на сервер отправляется неверная информация, которая затем сохраняется в базе данных.
Я хочу, чтобы мой код не позволял повторно отправлять действие increaseCategoryRank/decreaseCategoryRank
, если все запросы выборки не были успешно выполнены отправлено на сервер в действии fetchCategoryRanks
.
Однако я не уверен, как проверить, были ли отправлены все запросы перед отправкой действий increaseCategoryRank/decreaseCategoryRank
. Любые идеи приветствуются.