Scene: Fixing state issue with useState when SceneObject instance changes (#52372)

* ScenePanelRepeater: Fixes refreshes temporarily by setting key to guid

* Fixing issue with old state being returned by useState when the scene object instance changed (with same react key)
This commit is contained in:
Torkel Ödegaard 2022-07-19 17:47:59 +02:00 committed by GitHub
parent 8d92417a16
commit 16f813fc04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 4 deletions

View File

@ -1,8 +1,9 @@
import { useObservable } from 'react-use';
import { useEffect } from 'react';
import { Observer, Subject, Subscription } from 'rxjs';
import { v4 as uuidv4 } from 'uuid';
import { EventBusSrv } from '@grafana/data';
import { useForceUpdate } from '@grafana/ui';
import { SceneComponentWrapper } from './SceneComponentWrapper';
import { SceneObjectStateChangedEvent } from './events';
@ -118,7 +119,7 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
useState() {
// eslint-disable-next-line react-hooks/rules-of-hooks
return useObservable(this.subject, this.state);
return useSceneObjectState(this);
}
/**
@ -197,3 +198,18 @@ export abstract class SceneObjectBase<TState extends SceneObjectState = {}> impl
return new (this.constructor as any)(clonedState);
}
}
/**
* This hook is always returning model.state instead of a useState that remembers the last state emitted on the subject
* The reason for this is so that if the model instance change this function will always return the latest state.
*/
function useSceneObjectState<TState>(model: SceneObjectBase<TState>): TState {
const forceUpdate = useForceUpdate();
useEffect(() => {
const s = model.subject.subscribe(forceUpdate);
return () => s.unsubscribe();
}, [model, forceUpdate]);
return model.state;
}

View File

@ -78,7 +78,7 @@ export function getScenePanelRepeaterTest(): Scene {
uid: 'gdev-testdata',
type: 'testdata',
},
seriesCount: 5,
seriesCount: 2,
alias: '__server_names',
scenarioId: 'random_walk',
},
@ -119,7 +119,7 @@ export function getScenePanelRepeaterTest(): Scene {
$data: queryRunner,
actions: [
new SceneToolbarInput({
value: '5',
value: '2',
onChange: (newValue) => {
queryRunner.setState({
queries: [