src/legacy/store/recycleNodesInto.js
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule recycleNodesInto
* @flow
*/
'use strict';
/**
* Recycles subtrees from `prevData` by replacing equal subtrees in `nextData`.
*/
function recycleNodesInto<T>(prevData: T, nextData: T): T {
if (prevData === nextData ||
typeof prevData !== 'object' || !prevData ||
typeof nextData !== 'object' || !nextData) {
return nextData;
}
let canRecycle = false;
// Assign local variables to preserve Flow type refinement.
const prevArray = Array.isArray(prevData) ? prevData : null;
const nextArray = Array.isArray(nextData) ? nextData : null;
if (prevArray && nextArray) {
canRecycle =
nextArray.reduce((wasEqual, nextItem, ii) => {
nextArray[ii] = recycleNodesInto(prevArray[ii], nextItem);
return wasEqual && nextArray[ii] === prevArray[ii];
}, true) &&
prevArray.length === nextArray.length;
} else if (!prevArray && !nextArray) {
// Assign local variables to preserve Flow type refinement.
const prevObject = prevData;
const nextObject = nextData;
const prevKeys = Object.keys(prevObject);
const nextKeys = Object.keys(nextObject);
canRecycle =
nextKeys.reduce((wasEqual, key) => {
const nextValue = nextObject[key];
nextObject[key] = recycleNodesInto(prevObject[key], nextValue);
return wasEqual && nextObject[key] === prevObject[key];
}, true) &&
prevKeys.length === nextKeys.length;
}
return canRecycle ? prevData : nextData;
}
module.exports = recycleNodesInto;