2017-09-07 9 views
7

배열을 반환하는 선택기가 있습니다. 배열 자체의 요소에는 파생 데이터가 있습니다. 본질적으로 파생 된 요소로 구성된 파생 배열을 반환하는 재귀 적 메모 선택기가 필요합니다.둥지 넣기 선택기를 재 선택 하시겠습니까?

나의 현재의 시도는 여기

export const selectEntitesWithAssetBuffers = createSelector(
    [selectSceneEntities, getAssets], 
    (entities, loadedAssets) => { 
    return entities.map((entity) => { 
     entity.buffers = entity.assets.map((assetName) => { 
     return loadedAssets[assetName].arrayBuffer; 
     }) 
     return entity; 
    }) 
    } 
) 

내 문제는 언제든지이 전체 목록을 다시 계산합니다 entities 또는 loadedAssets 변화입니다. 내가 설정하고자하는 것은 selectEntityWithBuffer과 같은 것으로, entities.map으로 전달됩니다. 이상적으로, entity.assets 어레이가 변경 될 때만 이것을 다시 계산하기를 원합니다.

+0

'reselect-map'을 (를)보고있는 것이 내 목표와 일치 할 수 있습니다. https://www.npmjs.com/package/reselect-map – kevzettler

답변

2

재 선택을 사용하면 선택기에 사용자 정의 동등한 정의를 제공 할 수 있습니다.

import { defaultMemoize, createSelectorCreator } from 'reselect' 

const compareByAssets = (a, b) => { 
    return a.every((element, index) => { 
     return element.assets === b[index].assets 
    }); 
}; 

const createAssetsComparatorSelector = createSelectorCreator(
    defaultMemoize, 
    compareByAssets 
); 

const selectSceneEntitiesByAssetsComparator = createAssetsComparatorSelector((state) => { 
    //however you normally get entities for the pre-existing selectors 
}); 

지금 당신은 당신이 제공하는 위의 코드에서 이전 selectSceneEntities 대신이 새로운 selectSceneEntitiesByAssetsComparator을 사용할 수 있으며 compareByAssets에서 동등 검사가 실패 할 경우에만 다시 실행됩니다.

assets === assets의 엄격한 비교가 필요없는 경우 해당 비교 함수를 더 이상 업데이트 할 수 있습니다.

0

재검색은 선택자에게 인수를 전달하는 것을 실제로 지원하지 않기 때문에, 당신이 가지고있는 것보다 더 심한 메모를하는 것은 까다로운 문제입니다. 선택기에서 배열을 반환하고 해당 배열을 작성하는 데 사용 된 입력이 변경된 경우 다시 계산해야하는 다시 선택의 동작과 비슷합니다. 동적 인수에 대해서는 the advice in the readme을 참조하십시오.

3

개념 증명으로 을 우회하여 결과 함수에 loadedAssets 개체를 제공하려고합니다.

// Keep a private selector instance 
let cachedSelector; 

export const selectEntitesWithAssetBuffers = function(){ 
    // loadedAssets should be recalculated on each call? 
    const loadedAssets = getAssets(arguments); 

    // create selector on first call 
    if(cachedSelector === undefined) { 
     cachedSelector = createSelector(
      selectSceneEntities, 
      entities => { 
       return entities.map(entity => { 
        entity.buffers = entity.assets.map((assetName) => { 
         return loadedAssets[assetName].arrayBuffer; 
        }) 
        return entity; 
       }) 
      } 
     ) 
    } 

    // Return selector result 
    return cachedSelector(arguments); 
}