[英]Change state from reducer not from root state using React-Redux when data is inherited
下午好。 我正在使用 react-redux 编写应用程序并面临两难境地。 我已经重新思考了好几次,无法选择如何正确方便地组织项目和数据结构。 通过继承或组合数据来设计数据。 我最初是沿着作曲的道路走的,但我意识到当存在一对一的关系时很不方便。 我决定将其更改为 inheritance,因为从数据组织的角度来看这似乎是合乎逻辑的,但是reducers
有很大的困难,更准确地说,我很困惑,它原来是一个单根reducer
,有很多actionTypes
键。 我记得性能方面,当元素从共同祖先那里继承数据链时,这是非常糟糕的。 然而我选择了这条路,我有一个问题:请告诉我是否可以为每个级别的嵌套数据拆分成几个reducers
。 例子
onst initState: IPages = {
idActive: 0,
pages: [
{
id: 1,
title: `Tab #1`,
workspace: {
idActiveDraggableElements: [],
idActiveLines: [],
attributes: {
height: string,
width: string,
viewBox: [0, 0, 5000, 5000]
},
draggableElements: [], // more data
lines: [], // more data
}
},
]
}
减速器:
export function pagesReducer(
state: IPages = initState,
action: IPageActionTypes
) {
switch (action.type) {
case "ADD_PAGE":
let uniqId = getUniqKeyIdOfArrayList(state.pages);
return {
...state,
pages: state.pages.concat({id:uniqId, title:`Вкладка - ${uniqId}`})
}
case "REMOVE_PAGE": return {
...state,
pages: state.pages.filter(item => item.id !== action.id)
}
case "CHOSE_PAGE": return {
...state,
idActive: action.id
}
case "RENAME_PAGE":
let indexPage = state.pages.findIndex(item => item.id === action.id);
state.pages[indexPage].title = action.title;
return {
...state
}
// ===================
// LONG LIST WHAT BAD...
// It's a bad idea to add editing to the `workspace` field and then `draggableElements`. `lines`
// ... but I understand that this will happen, because I don't know if there is another way.
default:
return state
}
}
我可以在不更新整个应用程序 state 的情况下编辑“工作区”节点吗?
谢谢你的帮助。
对于一对一关系的数据建模方面,您可以选择通过 id 引用或嵌入数据。 这取决于您的查询模式。
在嵌入的情况下,您可以使用memoized selectors 。
理想情况下,由于您有一个idActive
,请将您的pages
数据结构更新为 object 而不是列表。
像这样:
{
pages: {
'1': {
workspace: { ... },
}
}
}
然后对于您的减速器,将其视为切片树(或嵌套属性)。 然后你的减速器看起来像:
function workspaceReducer(state, action) {
// TODO
}
function pagesReducer(state, action) {
switch (action.type) {
case 'UPDATE_WORKSPACE': {
const { id } = action;
const page = Object.assign({}, state.pages[id]);
return {
...state,
pages: {
...state.pages,
[id]: {
...page,
workspace: workspaceReducer(page.workspace, action)
}
}
}
}
}
}
然后为了防止不必要的重新渲染,使用记忆选择器,就像:
import { createSelector } from 'reselect';
const pages = state => state.pages;
const activePage = state => state.idActive;
const getActivePage = createSelector(
activePage,
pages,
(id, pages) => pages[id]
);
const getWorkspace = createSelector(
getActivePage,
page => page.workspace
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.