Reactjs 继承数据时,使用React Redux从reducer更改状态,而不是从根状态更改状态

Reactjs 继承数据时,使用React Redux从reducer更改状态,而不是从根状态更改状态,reactjs,redux,react-redux,Reactjs,Redux,React Redux,下午好。我正在使用react-redux编写一个应用程序,遇到了一个难题。我已经反复考虑了好几次,无法选择如何正确方便地组织项目和数据结构。通过继承或组合数据来设计数据。我最初是沿着作曲的道路走的,但我意识到当一对一的关系存在时,这是不方便的。我决定将其更改为继承,因为从数据组织的角度来看,它似乎是合乎逻辑的,但是reducer有一个很大的困难,更准确地说,我很困惑,它原来是一个单一的根reducer,有很多actionTypes键。我记得关于性能,当元素从一个共同的祖先继承数据链时,这是非常糟

下午好。我正在使用react-redux编写一个应用程序,遇到了一个难题。我已经反复考虑了好几次,无法选择如何正确方便地组织项目和数据结构。通过继承或组合数据来设计数据。我最初是沿着作曲的道路走的,但我意识到当一对一的关系存在时,这是不方便的。我决定将其更改为继承,因为从数据组织的角度来看,它似乎是合乎逻辑的,但是
reducer
有一个很大的困难,更准确地说,我很困惑,它原来是一个单一的根
reducer
,有很多
actionTypes
键。我记得关于性能,当元素从一个共同的祖先继承数据链时,这是非常糟糕的。然而,我选择了这条路径,我有一个问题:请告诉我,对于每一层嵌套数据,是否有可能拆分成几个
缩减器。范例

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引用或嵌入数据。这取决于您的查询模式

在嵌入的情况下,您可以利用

理想情况下,由于您有一个
i活动
,因此将
页面
数据结构更新为对象而不是列表

像这样:

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