Я менял редуктор страниц, но не элементы pageView, содержащиеся внутри (страницы имеют другой ключ, называемый данными, которые я обновлял). Итак, насколько я понимаю, selectPageViews не должен меняться (потому что базовые pageViews не меняются), и поэтому allPageViews должны просто запоминать, а не пересчитывать, потому что ничего не было обновлено.
Это правильно, состояние. page.pageViews не изменился, поэтому selectPageViews
вернет мемоизированный результат, как и allPageViews.
Тем не менее, вычисление производилось повторно. Когда я переместил массив returnPageViews и циклы for в компонент, который использовал useSelector (), компонент прекратил повторный рендеринг . Итак, мой вопрос: как работает Reselect, и почему он пересчитал и запустил повторную визуализацию , когда массив создавался в allPageViews?
Это не делает смысл, значит селектор не запускает повторный рендеринг? И Nonetheless it was re-calculating
неверно, вот ваш код ниже, демонстрирующий, что ваше первоначальное предположение было правильным; если вы не измените state.page.pageViews, тогда как selectPageViews, так и allPageViews вернут свой мемоизированный результат (пересчет не будет):
const { createSelector } = Reselect;
const getPages = (state) => {
return state.pages;
};
const attachPageViews = createSelector(
getPages,
(pages) => pages.pageViews
);
//this one is kind of useless, it does x=>x so you may as
// well do: const selectPageViews = attachPageViews
const selectPageViews = createSelector(
attachPageViews,
(pageViews) => {
console.log(
'selectPageViews logs once but is called twice'
);
return pageViews;
}
);
const allPageViews = createSelector(
selectPageViews,
(pageStore) => {
console.log(
'allPageViews logs once but is called twice'
);
return { new: 'object', pageStore };
}
);
const state = {
pages: {
pageViews: { value: 'this is page views' },
},
};
console.log('calling allPageViews first time');
const one = allPageViews(state);
console.log('calling allPageViews second time with changed state.pages');
const two = allPageViews({
...state,
pages: {
...state.pages,
changedSomething: true,
},
});
console.log('both results are the same:',one === two);
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
<div id="root"></div>