1

我有一个带有项目树(标准化)的 redux 状态,例如:

state = {
  items: [
    { id: 1, parent: null, children: [2, 3] },
    { id: 2, parent: 1, children: [4] },
    { id: 3, parent: 1, children: [], value: 10 },
    { id: 4, parent: 2, children: [], value: 20 }
  ]
}

我想获得项目 1 的值的减少总和(这里 = 10 + 20 = 30),我想为此创建一个重新选择选择器。

但是,如何定义递归选择器?

谢谢你的帮助。;-)

弗雷德里克

4

2 回答 2

1

我将更新@Vanojx1 代码以提出 2 个解决方案:

(免责声明:我是重新选择的作者,但这是一个典型的用例)

基本代码

let state = {
    items: [
        { id: 1, parent: null, children: [2, 3] },
        { id: 2, parent: 1, children: [4] },
        { id: 3, parent: 1, children: [], value: 10 },
        { id: 4, parent: 2, children: [], value: 20 }
    ]
};

function getSum(items, id) {
  let item = items.find(item => item.id == id);
  return item.hasOwnProperty('value') ? item.value : item.children.reduce((current, next) => {
    return current + getSum(items, next);
  }, 0);
}

解决方案 1 - 仅重新选择

import { createSelector } from 'reselect';

const getSumSelector = createSelector(
  (state) => state.items,
  (state, id) => id,
  (items, id) => getSum(items, id)
);

getSumSelector(state, 1);
// Loses memoization with sequentials calls with same items but different id's

解决方案 2 - 重新选择 + 重新选择

import createCachedSelector from 're-reselect';

const getSumSelector = createCachedSelector(
    state => state.items,
    (state, id) => id,
    (items, id) => getSum(items, id)
)(
    // Cache selector by id
    (state, id) => id
);

getSumSelector(state, 1);
于 2017-06-30T21:58:02.857 回答
0

尝试这个:

let state = {
    items: [
        { id: 1, parent: null, children: [2, 3] },
        { id: 2, parent: 1, children: [4] },
        { id: 3, parent: 1, children: [], value: 10 },
        { id: 4, parent: 2, children: [], value: 20 }
    ]
}

function getSum(state, id) {
  let item = state.items.find(item => item.id == id);
  return item.hasOwnProperty('value') ? item.value : item.children.reduce((current, next) => {
    return current + getSum(state, next);
  }, 0);
}

let sum = getSum(state, 1);

console.log(sum);

于 2017-06-26T14:35:42.530 回答