当数据被继承时,使用 React-Redux 从化简器而不是从根状态更改状态



下午好。我正在使用 react-redux 编写一个应用程序,并面临两难境地。我已经重新考虑了好几次,无法选择如何正确方便地组织项目和数据结构。通过继承或组合数据来设计数据。我最初走的是作文的道路,但我意识到当有一对一的关系时,这很不方便。我决定将其更改为继承,因为从数据组织的角度来看,这似乎是合乎逻辑的,但是reducers存在很大的困难,更准确地说,我很困惑,原来它是一个具有很多actionTypes键的单根reducer。我记得关于性能,当元素从共同祖先继承数据链时,这是非常糟糕的。然而,我选择了这条道路,我有一个问题:请告诉我是否可以为每个级别的嵌套数据分成几个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
}
}

是否可以在不更新整个应用程序状态的情况下编辑"工作区"节点?

感谢您的任何帮助。

对于一对一关系的数据建模方面,您可以选择按 id 引用或嵌入数据。这取决于您的查询模式。

在嵌入的情况下,您可以使用记忆选择器。

理想情况下,由于您有一个idActive,因此将pages数据结构更新为对象而不是列表。

这样:

{
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
);

最新更新