javascript - 为什么 redux 存储更改后连接的 React 组件不更新?
问题描述
我很好奇,为什么会发生这种情况。我知道,一切都按预期工作,我误解了这种行为。我正在为 react-redux 和 react 使用新的 hooks api。
const Categories = () => {
const dispatch = useDispatch();
const categoriesList = useSelector((state) => state.categories.categoriesList, shallowEqual);
// const isFetching = useSelector((state) => state.categories.isFetching);
console.log(categoriesList, 'categoriesList');
useEffect(() => {
dispatch(getCategoriesList());
dispatch(getTemplatesList());
}, [dispatch]);
return (
<ul className='categories-list'>
{categoriesList.map((category) => {
const {Fields: {Title, ID, IsActive, Path} = {}, SubCategoryList = []} = category;
return (
<CategoryItem
isActive={IsActive}
categoriesList={categoriesList}
categoryID={ID}
// isFetching={isFetching}
changeCategoryStatus={changeCategoryStatusRequest}
/>
);
})}
</ul>
);
};
的结构categoriesList
是这样的
[
{Info: {/**some info */}, SubCategoryList: [/**same structur like categoriesList */]},
{Info: {/**some info */}, SubCategoryList: [/**same structur like categoriesList */]},
{Info: {/**some info */}, SubCategoryList: [/**same structur like categoriesList */]},
{Info: {/**some info */}, SubCategoryList: [/**same structur like categoriesList */]},
{Info: {/**some info */}, SubCategoryList: [/**same structur like categoriesList */]},
];
在我的CategoryItem组件中单击某个按钮后,它会调度一个操作,该操作会获取特定类别的新数据,主要目的是更改属性isActive
。获得新数据后,我更新categoriesList
它,它可能是 X 级最深的类别,其isActive
prop 会发生变化。更改后,假定categoriesList
已更新(甚至是深度更新)。但是我的组件不会再次运行,也不会更新isActive
状态。实际上组件接收该道具,我认为应该重新渲染它。您可以注意到,我评论了isFetching
属性(在获取新数据和更新后它也发生了变化categoriesList
)。使用该属性,我的组件会再次呈现并更改isActive
支柱。乍一看,我认为问题在于深度嵌套的值,但我用另一个 react-redux 项目在sandbox
. 在这种情况下,组件会在更改后呈现value
。
deep: {
deep2: {
value: 0
}
}
那么主要区别是什么?我怎样才能正确理解它?提前致谢。
更新-Here is my reducer
import * as types from '../types';
import {createReducer} from '../../helpers/utilities';
import _ from 'lodash';
const initialState = {
categoriesList: [],
actionResult: null,
isFetching: false,
category: {},
};
const changeCategoryStatus = (state, action) => {
const {payload} = action;
const updateFunction = (category) => {
if (category.Fields.ID === payload.ID) {
category.Fields.IsActive = payload.IsActive;
return false;
}
Array.isArray( category.SubCategoryList) && _.forEach(category.SubCategoryList, updateFunction);
};
const changedCategoriesList = _.forEach(state.categoriesList, updateFunction);
return updateStore(state, {
actionResult: hasError(payload) ? {
type: 'error',
message: payload.message,
} : null,
isFetching: false,
categoriesList: changedCategoriesList,
});
};
const handlers = {
[types.CATEGORY_STATUS_RESPONSE]: changeCategoryStatus,
};
export default createReducer(initialState, handlers);
解决方案
推荐阅读
- javascript - 使用 querySelectorAll() 选择列表的第二个元素
- batch-file - 批处理 - 如何创建多个文本文件?
- java - 在 Visual Studio 设置中设置 java.home 或 xml.java.home
- php - 在 belonsToMany 关系上使用 withPivot 时限制检索的列
- python - 使用另一个数据框的值,根据列名乘以熊猫数据框的行
- javascript - 修改嵌套对象数组的所有元素中的属性的最佳方法
- c++ - 防止 CIN 上的多个输入
- android - 如何从 Firebase 数据库中删除此特定节点?
- javascript - Jmeter 脚本重放问题 - 请启用 JavaScript 以查看页面内容
- swift - 使用带有布尔运算符的字符串 Swift