mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Clean up generic hooks, use react-use instead (#53822) As we recently added react-use as a dependency, makes sense to clean up those generic hooks from Kibana repo. Removed custom hooks from kibana_react and other places: useObservable useUnmount useShallowCompareEffect react-use should be used instead: import useObservable from 'react-use/lib/useObservable' # Conflicts: # src/plugins/kibana_react/public/index.ts # x-pack/legacy/plugins/apm/public/context/LicenseContext/index.tsx * fix merge
This commit is contained in:
parent
6f6aacb61a
commit
c3f1d973e8
16 changed files with 26 additions and 321 deletions
|
@ -231,7 +231,7 @@
|
|||
"react-resize-detector": "^4.2.0",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-sizeme": "^2.3.6",
|
||||
"react-use": "^13.10.2",
|
||||
"react-use": "^13.13.0",
|
||||
"reactcss": "1.2.3",
|
||||
"redux": "4.0.0",
|
||||
"redux-actions": "2.2.1",
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
import React, { useReducer, useEffect, useMemo } from 'react';
|
||||
import { EuiForm, EuiAccordion, EuiSpacer, EuiFormRow } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import useUnmount from 'react-use/lib/useUnmount';
|
||||
|
||||
import { VisState } from 'ui/vis';
|
||||
import { aggTypes, AggType, AggParam, AggConfig } from 'ui/agg_types/';
|
||||
import { IndexPattern } from 'ui/index_patterns';
|
||||
import { aggTypes, AggType, AggParam, AggConfig } from 'ui/agg_types/';
|
||||
|
||||
import { DefaultEditorAggSelect } from './agg_select';
|
||||
import { DefaultEditorAggParam } from './agg_param';
|
||||
|
@ -44,9 +45,6 @@ import {
|
|||
} from './agg_params_state';
|
||||
import { editorConfigProviders } from '../../config/editor_config_providers';
|
||||
import { FixedParam, TimeIntervalParam, EditorParamConfig } from '../../config/types';
|
||||
// TODO: Below import is temporary, use `react-use` lib instead.
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { useUnmount } from '../../../../../../../plugins/kibana_react/public/util/use_unmount';
|
||||
import { AggGroupNames } from '../agg_groups';
|
||||
import { OnAggParamsChange } from './agg_common_props';
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import React from 'react';
|
|||
import classNames from 'classnames';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import useShallowCompareEffect from 'react-use/lib/useShallowCompareEffect';
|
||||
import { EuiLoadingChart, EuiProgress } from '@elastic/eui';
|
||||
import theme from '@elastic/eui/dist/eui_theme_light.json';
|
||||
import { useShallowCompareEffect } from '../../kibana_react/public';
|
||||
import { IExpressionLoaderParams, IInterpreterRenderHandlers, RenderError } from './types';
|
||||
import { ExpressionAST } from '../common/types';
|
||||
import { ExpressionLoader } from './loader';
|
||||
|
|
|
@ -25,4 +25,4 @@ export * from './overlays';
|
|||
export * from './ui_settings';
|
||||
export * from './field_icon';
|
||||
export * from './table_list_view';
|
||||
export { toMountPoint, useShallowCompareEffect } from './util';
|
||||
export { toMountPoint } from './util';
|
||||
|
|
|
@ -24,10 +24,10 @@ import { useUiSetting$ } from './use_ui_setting';
|
|||
import { createKibanaReactContext } from '../context';
|
||||
import { KibanaServices } from '../context/types';
|
||||
import { Subject } from 'rxjs';
|
||||
import { useObservable } from '../util/use_observable';
|
||||
import { coreMock } from '../../../../core/public/mocks';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
jest.mock('../util/use_observable');
|
||||
jest.mock('react-use/lib/useObservable');
|
||||
const useObservableSpy = (useObservable as any) as jest.SpyInstance;
|
||||
useObservableSpy.mockImplementation((observable, def) => def);
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
*/
|
||||
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { useKibana } from '../context';
|
||||
import { useObservable } from '../util/use_observable';
|
||||
|
||||
/**
|
||||
* Returns the current UI-settings value.
|
||||
|
|
|
@ -17,7 +17,4 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
export * from './use_observable';
|
||||
export * from './use_unmount';
|
||||
export * from './react_mount';
|
||||
export * from './use_shallow_compare_effect';
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { Subject } from 'rxjs';
|
||||
import { useObservable } from './use_observable';
|
||||
|
||||
test('default initial value is undefined', () => {
|
||||
const subject$ = new Subject();
|
||||
const { result } = renderHook(() => useObservable(subject$));
|
||||
|
||||
expect(result.current).toBe(undefined);
|
||||
});
|
||||
|
||||
test('can specify initial value', () => {
|
||||
const subject$ = new Subject();
|
||||
const { result } = renderHook(() => useObservable(subject$, 123));
|
||||
|
||||
expect(result.current).toBe(123);
|
||||
});
|
||||
|
||||
test('returns the latest value of observables', () => {
|
||||
const subject$ = new Subject();
|
||||
const { result } = renderHook(() => useObservable(subject$, 123));
|
||||
|
||||
act(() => {
|
||||
subject$.next(125);
|
||||
});
|
||||
expect(result.current).toBe(125);
|
||||
|
||||
act(() => {
|
||||
subject$.next(300);
|
||||
subject$.next(400);
|
||||
});
|
||||
expect(result.current).toBe(400);
|
||||
});
|
||||
|
||||
xtest('subscribes to observable only once', () => {});
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { useLayoutEffect, useState } from 'react';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export function useObservable<T>(observable$: Observable<T>): T | undefined;
|
||||
export function useObservable<T>(observable$: Observable<T>, initialValue: T): T;
|
||||
export function useObservable<T>(observable$: Observable<T>, initialValue?: T): T | undefined {
|
||||
const [value, update] = useState<T | undefined>(initialValue);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const s = observable$.subscribe(update);
|
||||
return () => s.unsubscribe();
|
||||
}, [observable$]);
|
||||
|
||||
return value;
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { useShallowCompareEffect } from './use_shallow_compare_effect';
|
||||
|
||||
describe('useShallowCompareEffect', () => {
|
||||
test("doesn't run effect on shallow change", () => {
|
||||
const callback = jest.fn();
|
||||
let deps = [1, { a: 'b' }, true];
|
||||
const { rerender } = renderHook(() => useShallowCompareEffect(callback, deps));
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
|
||||
// no change
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
callback.mockClear();
|
||||
|
||||
// no-change (new object with same properties)
|
||||
deps = [1, { a: 'b' }, true];
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
callback.mockClear();
|
||||
|
||||
// change (new primitive value)
|
||||
deps = [2, { a: 'b' }, true];
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
|
||||
// no-change
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
callback.mockClear();
|
||||
|
||||
// change (new primitive value)
|
||||
deps = [1, { a: 'b' }, false];
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
|
||||
// change (new properties on object)
|
||||
deps = [1, { a: 'c' }, false];
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
});
|
||||
|
||||
test('runs effect on deep change', () => {
|
||||
const callback = jest.fn();
|
||||
let deps = [1, { a: { b: 'c' } }, true];
|
||||
const { rerender } = renderHook(() => useShallowCompareEffect(callback, deps));
|
||||
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
|
||||
// no change
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(0);
|
||||
callback.mockClear();
|
||||
|
||||
// change (new nested object )
|
||||
deps = [1, { a: { b: 'c' } }, true];
|
||||
rerender();
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
callback.mockClear();
|
||||
});
|
||||
});
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
/**
|
||||
* Similar to https://github.com/kentcdodds/use-deep-compare-effect
|
||||
* but uses shallow compare instead of deep
|
||||
*/
|
||||
export function useShallowCompareEffect(
|
||||
callback: React.EffectCallback,
|
||||
deps: React.DependencyList
|
||||
) {
|
||||
useEffect(callback, useShallowCompareMemoize(deps));
|
||||
}
|
||||
function useShallowCompareMemoize(deps: React.DependencyList) {
|
||||
const ref = useRef<React.DependencyList | undefined>(undefined);
|
||||
|
||||
if (!ref.current || deps.some((dep, index) => !shallowEqual(dep, ref.current![index]))) {
|
||||
ref.current = deps;
|
||||
}
|
||||
|
||||
return ref.current;
|
||||
}
|
||||
// https://github.com/facebook/fbjs/blob/master/packages/fbjs/src/core/shallowEqual.js
|
||||
function shallowEqual(objA: any, objB: any): boolean {
|
||||
if (is(objA, objB)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const keysA = Object.keys(objA);
|
||||
const keysB = Object.keys(objB);
|
||||
|
||||
if (keysA.length !== keysB.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test for A's keys different from B.
|
||||
for (let i = 0; i < keysA.length; i++) {
|
||||
if (
|
||||
!Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
|
||||
!is(objA[keysA[i]], objB[keysA[i]])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* IE11 does not support Object.is
|
||||
*/
|
||||
function is(x: any, y: any): boolean {
|
||||
if (x === y) {
|
||||
return x !== 0 || y !== 0 || 1 / x === 1 / y;
|
||||
} else {
|
||||
return x !== x && y !== y;
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export function useUnmount(fn: () => void): void {
|
||||
useEffect(() => fn, []);
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { npSetup } from 'ui/new_platform';
|
||||
import { useObservable } from './use_observable';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
/**
|
||||
* This hook behaves like a `useState` hook in that it provides a requested
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
export function useObservable<T>(observable$: Observable<T>): T | undefined;
|
||||
export function useObservable<T>(observable$: Observable<T>, initialValue: T): T;
|
||||
export function useObservable<T>(observable$: Observable<T>, initialValue?: T): T | undefined {
|
||||
const [value, update] = useState<T | undefined>(initialValue);
|
||||
|
||||
useEffect(() => {
|
||||
const s = observable$.subscribe(update);
|
||||
return () => s.unsubscribe();
|
||||
}, [observable$]);
|
||||
|
||||
return value;
|
||||
}
|
|
@ -7,10 +7,7 @@
|
|||
import classNames from 'classnames';
|
||||
import React, { useRef, FC } from 'react';
|
||||
import { TooltipValueFormatter } from '@elastic/charts';
|
||||
|
||||
// TODO: Below import is temporary, use `react-use` lib instead.
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { useObservable } from '../../../../../../../../src/plugins/kibana_react/public/util/use_observable';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
|
||||
import { chartTooltip$, ChartTooltipValue } from './chart_tooltip_service';
|
||||
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -5185,6 +5185,11 @@
|
|||
dependencies:
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@xobotyi/scrollbar-width@1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.5.0.tgz#488210bff634548040dc22a72f62722a85b134e1"
|
||||
integrity sha512-BK+HR1D00F2xh7n4+5en8/dMkG13uvIXLmEbsjtc1702b7+VwXkvlBDKoRPJMbkRN5hD7VqWa3nS9fNT8JG3CA==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
|
@ -12940,6 +12945,11 @@ fast-safe-stringify@^2.0.7:
|
|||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fast-shallow-equal@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-0.1.1.tgz#44d01324d7fd31e00a67bb02b9396e283d526c22"
|
||||
integrity sha512-XVP6nhaXLYOH6JZCWBcNaeEer9GJ5/8cJWUP+OLmgwWgEkJp5Kpl/fdpJ01zl0mpLxrk7f5J3hIv+GmjTCi7Mg==
|
||||
|
||||
fast-stream-to-buffer@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-stream-to-buffer/-/fast-stream-to-buffer-1.0.0.tgz#793340cc753e7ec9c7fb6d57a53a0b911cb0f588"
|
||||
|
@ -24283,12 +24293,14 @@ react-transition-group@^2.2.1:
|
|||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-use@^13.10.2:
|
||||
version "13.10.2"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-13.10.2.tgz#4250d258ca9068662943299c01794a136408c8e9"
|
||||
integrity sha512-z3VFSiPHW6arViGVnajO7YKY5OD+Z9LWcImoJdYHkau23cLSoTctxM3XENLpGxjhJlHaYiQZ6pPgq7pwGTqSZA==
|
||||
react-use@^13.13.0:
|
||||
version "13.13.0"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-13.13.0.tgz#5d133c4d4d8d3f21f6ccf4ccbe54fbcd6fdafb36"
|
||||
integrity sha512-J3/h5wvL6vXmecAvEnninCC3DviLMRWcQrEnouTliwws1b376DQKEgIFuTXlF8c3SKpXBQJdDDm1RpluokW6ag==
|
||||
dependencies:
|
||||
"@xobotyi/scrollbar-width" "1.5.0"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
fast-shallow-equal "^0.1.1"
|
||||
nano-css "^5.2.1"
|
||||
react-fast-compare "^2.0.4"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue