mirror of
https://github.com/grafana/grafana.git
synced 2024-12-24 16:10:22 -06:00
influxdb: raw-influxql editor: fix state-management bug (#32035)
* influxdb: raw-influxql editor: state-management bug fixed * influxdb: simplified code
This commit is contained in:
parent
3a841ebe00
commit
8285a34f4c
@ -2,7 +2,7 @@ import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import { useShadowedState } from './useShadowedState';
|
||||
|
||||
describe('useShadowedState', () => {
|
||||
it('should work correctly', () => {
|
||||
it('should handle outside changes', () => {
|
||||
const { result, rerender } = renderHook(({ outsideVal }) => useShadowedState(outsideVal), {
|
||||
initialProps: { outsideVal: '42' },
|
||||
});
|
||||
@ -24,4 +24,44 @@ describe('useShadowedState', () => {
|
||||
// and verify the now has the value from the outside
|
||||
expect(result.current[0]).toBe('71');
|
||||
});
|
||||
it('should handle changs applied from inside to outside', () => {
|
||||
// this is a test-case created because of a bug that was
|
||||
// found with this component, it happens when:
|
||||
// 1. the value is changed inside
|
||||
// 2. the inside-value gets applied to the outside-component,
|
||||
// so now the outside-value again matches the inside-value
|
||||
// 3. the value changes again inside
|
||||
// at this point the value should be correct.
|
||||
const { result, rerender } = renderHook(({ outsideVal }) => useShadowedState(outsideVal), {
|
||||
initialProps: { outsideVal: '1' },
|
||||
});
|
||||
|
||||
// first we verify it has the initial value
|
||||
expect(result.current[0]).toBe('1');
|
||||
|
||||
// then we change it
|
||||
act(() => {
|
||||
result.current[1]('2');
|
||||
});
|
||||
|
||||
// and verify it has the changed value
|
||||
expect(result.current[0]).toBe('2');
|
||||
|
||||
// then we change the value from the outside to the same
|
||||
// value as the one inside (2)
|
||||
// (this simulates the case when the inside value gets
|
||||
// propageted to the outside component)
|
||||
rerender({ outsideVal: '2' });
|
||||
|
||||
// and verify the the value is ok
|
||||
expect(result.current[0]).toBe('2');
|
||||
|
||||
// and now change the inside-value again
|
||||
act(() => {
|
||||
result.current[1]('3');
|
||||
});
|
||||
|
||||
// and verify the the value is ok
|
||||
expect(result.current[0]).toBe('3');
|
||||
});
|
||||
});
|
||||
|
@ -1,13 +1,15 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { usePrevious } from 'react-use';
|
||||
|
||||
export function useShadowedState<T>(outsideVal: T): [T, (newVal: T) => void] {
|
||||
const [currentVal, setCurrentVal] = useState(outsideVal);
|
||||
const prevOutsideVal = useRef(outsideVal);
|
||||
const prevOutsideVal = usePrevious(outsideVal);
|
||||
|
||||
useEffect(() => {
|
||||
// if the value changes from the outside, we accept it
|
||||
if (prevOutsideVal.current !== outsideVal && currentVal !== outsideVal) {
|
||||
prevOutsideVal.current = outsideVal;
|
||||
const isOutsideValChanged = prevOutsideVal !== outsideVal;
|
||||
// if the value changes from the outside, we accept it into the state
|
||||
// (we only set it if it is different from the current value)
|
||||
if (isOutsideValChanged && currentVal !== outsideVal) {
|
||||
setCurrentVal(outsideVal);
|
||||
}
|
||||
}, [outsideVal, currentVal]);
|
||||
|
Loading…
Reference in New Issue
Block a user