我同时学习了React和Redux,并全力投入Redux。基本上所有状态都存储在Redux中。我遵循标准的allIds
,byId
状态形状模式as detailed here。
我的应用程序非常以数据为中心,它与API通讯,并且执行许多CRUD类型的操作-fetchAll,fetchById,添加,更新,删除。
API通信被隔离到一个“服务层”模块中,该模块是其自己的npm软件包。使用redux-thunk在Redux操作中对此服务层的所有调用。
我已经意识到不需要将所有内容都放在Redux中,例如,确实需要在特定组件上使用数据。而且,我想简化这种架构。
因此,我开始重构为自定义钩子。似乎因为状态状态更多地是对象而不是标量,所以我应该使用useReducer
而不是useState
...
// reducer
// -------------------------
const initialState = {
adding: false,updating: false,deleting: false,error: null,items: null
};
const reducer = (state,action) => {
// implementation omitted for brevity. . .
}
const useItemsApi = () => {
const [state,dispatch] = useReducer(reducer,initialState);
// wrapped in useCallback because called in component's useEffect
const fetchItems = useCallback(async (options) => {
try {
const resp = apiService.fetchItems(options);
} catch (err) {
if(err.status === 401)
// send to login screen
else
dispatch({type: 'error',payload: err});
}
},[options]);
// addItem,updateItem,deleteItem,etc...
const actions = {fetchItems,addItem,deleteItem};
return [state,actions];
};
// component
// -------------------------
const component = (props) => {
const [state,actions] = useItemsApi();
const {fetchItems,deleteItem} = actions;
useEffect(() => {
fetchItems()
},fetchItems);
// omitted for brevity...
}
当我需要在化简器中为更新操作设置状态时,我意识到如果使用“ allIds”和“ byId”模式会更容易。
在这一点上,我想-与使用Redux有什么不同?
最终看起来几乎是完全相同的代码,我失去了选择器的某些功能,但消除了redux-thunk的复杂性。而且我当前的redux动作包括特定的用例动作(例如,对于项目类型X的特殊保存),所以我需要为这些地方找到一个地方。
我的问题是-是否有任何理由使用本地状态将其重构为一个钩子?