Я недавно начал использовать избыточность, потому что увидел много потенциальных преимуществ в использовании единого дерева состояний для всего приложения. Однако есть одна проблема, с которой я продолжаю сталкиваться; когда я отправляю последовательные обновления хранилища, последнее обновление не знает об изменениях хранилища предыдущего обновления.
Например, скажем, у меня есть функция getCoffee (), и getCoffee () заполняет мою чашку кофе, а затем вызывает addCream () внутренне. После заполнения моей чашки кофе (на самом деле я не люблю сливки в моем кофе) getCream () добавил бы сливки, но не знал бы, что getCoffee () наполнил мою чашку кофе, и я бы в итоге только чашку сливок.
Я провел мозговой штурм по нескольким решениям, которые, я уверен, сработают, но меня больше интересует, как я мог go сообщить о нескольких действиях, когда последний знал об обновленном состоянии приложения. В настоящее время я использую componentDidUpdate (), чтобы проверить наличие определенных изменений, а затем выполнить соответствующее обновление, но выполнение нескольких обновлений усложняет ситуацию.
Вот код:
// Toggles display of search bar and calls getResults() if the input field is not empty this
handleSearch(event) {
const input = document.getElementById('recipe-name');
// Hides other search tools besides current search tool
this.hideSearchTools(event);
if(input.style.width === '0vw' || !input.style.width) {
// Renders searchbar
input.style.width = '70vw';
input.style.padding = '10px 15px'
input.style.boxShadow = '2px 2px 10px 1px rgba(0, 0, 0, .2)';
input.disabled = false;
} else if(input.style.width === '70vw' && !input.value) {
// Hides searchbar if input field is empty
input.style.width = '0vw';
input.style.padding = '10px 0px';
input.disabled = true;
} else {
// Perform search clear current query and hides searchbar
input.style.width = '0vw';
input.style.padding = '10px 0px';
input.value = '';
input.disabled = true;
if(this.props.recipesUI.results.recipes.length) {
// If there was previous search clears filters and sort slice of state
const nutrientFilters = [];
const foodTypeFilters = [];
const foodLabelFilters = [];
const sort = {
type: null,
criteria: null,
isNutrient: null
};
// Updates store with all filters and sort set to initial state
this.props.updateRecipesUI(Object.assign({}, this.props.recipesUI, { nutrientFilters, foodTypeFilters, foodLabelFilters, sort }));
};
this.getResults();
};
}
// Applies filters to a query sends off query to server, sorts if necessary and stores results in app state
getResults() {
let ui = { ...this.props.recipesUI };
let { sort, nutrientFilters, foodTypeFilters, foodLabelFilters } = ui;
if(!ui.query) {
return;
};
let path = "https://path/to/api?";
let query = 'q=' + ui.query.split(' ').join('%20');
path = path.concat(query);
// Helpers that build our query based on existing filters
path = path.concat(nutrientParams(nutrientFilters));
path = path.concat(typeParams(foodTypeFilters));
path = path.concat(labelParams(foodLabelFilters));
// Updates searching to true before request is initiated
this.props.updateRecipesUI(Object.assign({}, ui, {searching: true}));
fetch(`/api/recipes?path=${path}`)
.then(res => res.json())
.then(res => {
let results = {
...res,
currentPage: 0,
sortedRecipes: []
};
let { recipes } = results;
this.props.updateRecipesUI(Object.assign({}, ui, { results, searching: false }));
if(sort.criteria) {
this.sortRecipes();
};
});
}
// Initial App State as far as Recipes.js and children are concerned
const initState = {
recipesUI: {
results: {
recipes: [],
sortedRecipes: [],
q: null,
count: null,
currentPage: null
},
searching: false,
query: null,
nutrientFilters: [],
foodTypeFilters: [],
foodLabelFilters: [],
filtersToApply: [],
filtersToRemove: [],
sort: {
type: null,
criteria: null,
isNutrient: null
}
}}
В настоящее время handleSearch () либо отображает панель поиска, либо скрывает ее, либо скрывает и запускает поиск (в зависимости от состояния панели поиска, которая является просто элементом ввода). Если последнее условие выполнено, вызывается getResults (), который обрабатывает создание запроса и отправку его на сервер. Перед отправкой нашего запроса установка состояния загрузки в true перезаписывает сброс состояния в конце handleSearch ().
Заранее спасибо!
Редактировать: Возможно, причина, по которой последнее обновление магазина сохраняется по сравнению с предыдущим, заключается в том, что вторая функция запускается, когда хранилище еще не отразило изменения, сделанные в handleSearch ( ).