Skip to content

Commit

Permalink
[APM] Prevent infinite loop when updating time range (#109043) (#109146)
Browse files Browse the repository at this point in the history
Closes #108983.

Co-authored-by: Dario Gieselaar <[email protected]>
  • Loading branch information
kibanamachine and dgieselaar authored Aug 18, 2021
1 parent d7e1ad5 commit 3d1bde7
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 37 deletions.
39 changes: 14 additions & 25 deletions x-pack/plugins/apm/public/hooks/use_time_range.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
act,
renderHook,
RenderHookResult,
} from '@testing-library/react-hooks';
import { renderHook, RenderHookResult } from '@testing-library/react-hooks';
import { useTimeRange } from './use_time_range';

describe('useTimeRange', () => {
Expand All @@ -29,40 +25,33 @@ describe('useTimeRange', () => {
);
});

afterEach(() => {});

it('returns the parsed range on first render', () => {
expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z');
});

it('only changes the parsed range when rangeFrom/rangeTo change', () => {
Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 13)).valueOf());

hook.rerender({ rangeFrom: 'now-15m', rangeTo: 'now' });

expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z');

hook.rerender({ rangeFrom: 'now-30m', rangeTo: 'now' });

expect(hook.result.current.start).toEqual('2021-01-01T12:30:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T13:00:00.000Z');
});
expect(hook.result.current.start).toEqual('2021-01-01T11:30:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z');

it('updates when refreshTimeRange is called', async () => {
Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 13)).valueOf());

hook.rerender({ rangeFrom: 'now-15m', rangeTo: 'now' });
hook.rerender({ rangeFrom: 'now-30m', rangeTo: 'now' });

expect(hook.result.current.start).toEqual('2021-01-01T11:45:00.000Z');
// times should not change, because rangeFrom/rangeTo did not change
expect(hook.result.current.start).toEqual('2021-01-01T11:30:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:00:00.000Z');

act(() => {
hook.result.current.refreshTimeRange();
});
hook.rerender({ rangeFrom: 'now-30m', rangeTo: 'now-15m' });

expect(hook.result.current.start).toEqual('2021-01-01T12:30:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:45:00.000Z');

hook.rerender({ rangeFrom: 'now-45m', rangeTo: 'now-30m' });

expect(hook.result.current.start).toEqual('2021-01-01T12:45:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T13:00:00.000Z');
expect(hook.result.current.start).toEqual('2021-01-01T12:15:00.000Z');
expect(hook.result.current.end).toEqual('2021-01-01T12:30:00.000Z');
});
});
17 changes: 5 additions & 12 deletions x-pack/plugins/apm/public/hooks/use_time_range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import { isEqual } from 'lodash';
import { useCallback, useRef, useState } from 'react';
import { useRef } from 'react';
import { getDateRange } from '../context/url_params_context/helpers';

export function useTimeRange({
Expand All @@ -18,24 +18,19 @@ export function useTimeRange({
}) {
const rangeRef = useRef({ rangeFrom, rangeTo });

const [timeRangeId, setTimeRangeId] = useState(0);

const stateRef = useRef(getDateRange({ state: {}, rangeFrom, rangeTo }));

const updateParsedTime = useCallback(() => {
const updateParsedTime = () => {
stateRef.current = getDateRange({ state: {}, rangeFrom, rangeTo });
}, [rangeFrom, rangeTo]);
};

if (!isEqual(rangeRef.current, { rangeFrom, rangeTo })) {
updateParsedTime();
}

const { start, end } = stateRef.current;
rangeRef.current = { rangeFrom, rangeTo };

const refreshTimeRange = useCallback(() => {
updateParsedTime();
setTimeRangeId((id) => id + 1);
}, [setTimeRangeId, updateParsedTime]);
const { start, end } = stateRef.current;

if (!start || !end) {
throw new Error('start and/or end were unexpectedly not set');
Expand All @@ -44,7 +39,5 @@ export function useTimeRange({
return {
start,
end,
refreshTimeRange,
timeRangeId,
};
}

0 comments on commit 3d1bde7

Please sign in to comment.