Skip to content

Commit

Permalink
Merge pull request #2166 from Shopify/add-lazy-ref
Browse files Browse the repository at this point in the history
Add useLazyRef hook
  • Loading branch information
AndrewMusgrave authored Sep 19, 2019
2 parents 1142a98 + 3a28fed commit 1078041
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f

### Code quality

- Added `useLazyRef` hook to use while building components ([#2166](https://github.com/Shopify/polaris-react/pull/2166))
- Migrated `FilterCreator` to use hooks instead of withAppProvider ([#2156](https://github.com/Shopify/polaris-react/pull/2156))
- Created a custom error for lack of context providers ([#2136](https://github.com/Shopify/polaris-react/pull/2136))
- Migrated `ContextualSaveBar` to use hooks instead of `withAppProvider` ([#2091](https://github.com/Shopify/polaris-react/pull/2091))
Expand Down
37 changes: 37 additions & 0 deletions src/utilities/tests/use-lazy-ref.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, {useEffect, useState} from 'react';
import {mount} from 'test-utilities';
import {useLazyRef} from '../use-lazy-ref';

describe('useLazyRef', () => {
it('returns a ref object', () => {
const spy = jest.fn();

function MockComponent() {
const lazyValue = useLazyRef(() => true);
spy(lazyValue);
return null;
}

mount(<MockComponent />);
expect(spy).toHaveBeenCalledWith({current: true});
});

it('only calls initialValue once', () => {
const spy = jest.fn();

function MockComponent() {
const [, setFooState] = useState(false);

useEffect(() => {
setFooState(true);
}, []);

useLazyRef(spy);

return null;
}

mount(<MockComponent />);
expect(spy).toHaveBeenCalledTimes(1);
});
});
22 changes: 22 additions & 0 deletions src/utilities/use-lazy-ref.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {useRef, MutableRefObject} from 'react';

const UNIQUE_IDENTIFIER = Symbol('unique_identifier');

/**
* useLazyRef provides a lazy initial value, similar to lazy
* initial state the initialValue is the value used during
* initialization and disregarded after that.
* @param initialValue - A function that will return the initial
* value and be disregarded after that
* @returns MutableRefObject<T> - Returns a ref object with the
* results from invoking initial value
*/
export function useLazyRef<T>(initialValue: () => T) {
const lazyRef = useRef<T | Symbol>(UNIQUE_IDENTIFIER);

if (lazyRef.current === UNIQUE_IDENTIFIER) {
lazyRef.current = initialValue();
}

return lazyRef as MutableRefObject<T>;
}

0 comments on commit 1078041

Please sign in to comment.