/**
* Copyright (c) 2017-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.
*
* @flow
* @format
*/
import invariant from 'assert';
import {arrayEqual} from './collection';
type memoizeUntilChanged = ((
func: (A, B, C, D) => R,
keySelector_?: (A, B, C, D) => U,
compareKeys_?: (U, U) => boolean,
) => (A, B, C, D) => R) &
((
func: (A, B, C) => R,
keySelector_?: (A, B, C) => U,
compareKeys_?: (U, U) => boolean,
) => (A, B, C) => R) &
((
func: (A, B) => R,
keySelector_?: (A, B) => U,
compareKeys_?: (U, U) => boolean,
) => (A, B) => R) &
((
func: (A) => R,
keySelector_?: (A) => U,
compareKeys_?: (U, U) => boolean,
) => A => R) &
((func: () => R) => () => R) &
((
func: (...any: $ReadOnlyArray) => R,
(...any: $ReadOnlyArray) => U,
compareKeys_?: (U, U) => boolean,
) => (...any: $ReadOnlyArray) => R);
/**
* Create a memoized version of the provided function that caches only the latest result. This is
* especially useful for optimizing React component methods without having to worry about
* maintaining state explicitly. For example:
*
* class MyComponent extends React.Component {
* constructor(props) {
* super(props);
* this._computeSomethingExpensive = memoizeUntilChanged(this._computeSomethingExpensive);
* }
* _computeSomethingExpensive(x) { ... }
* render() {
* const thingToRender = this._computeSomethingExpensive(this.props.value);
* return {thingToRender}
;
* }
* }
*
* Sometimes, you need to customize how the arguments are compared. In this case you can pass a
* key selector function (which derives a single value from the arguments), and an equality function
* (which compares keys). For example:
*
* class MyComponent extends React.Component {
* constructor(props) {
* super(props);
* this._computeSomethingExpensive = memoizeUntilChanged(
* this._computeSomethingExpensive,
* (x: Array