Graphite: Run onChange/onRunQuery after reducer action finishes (#42136) (#42224)

(cherry picked from commit b3e417f768)

Co-authored-by: Piotr Jamróz <pm.jamroz@gmail.com>
This commit is contained in:
Grot (@grafanabot) 2021-11-24 08:37:24 -05:00 committed by GitHub
parent dfdb745e36
commit 01a53c349a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 8 deletions

View File

@ -31,6 +31,7 @@ export const GraphiteQueryEditorContext = ({
children,
}: PropsWithChildren<GraphiteQueryEditorProps>) => {
const [state, setState] = useState<GraphiteQueryEditorState>();
const [needsRefresh, setNeedsRefresh] = useState<boolean>(false);
const dispatch = useMemo(() => {
return createStore((state) => {
@ -68,6 +69,19 @@ export const GraphiteQueryEditorContext = ({
[dispatch, query]
);
useEffect(
() => {
if (needsRefresh && state) {
setNeedsRefresh(false);
onChange({ ...query, target: state.target.target });
onRunQuery();
}
},
// adding state to dependencies causes infinite loops
// eslint-disable-next-line react-hooks/exhaustive-deps
[needsRefresh, onChange, onRunQuery, query]
);
if (!state) {
dispatch(
actions.init({
@ -78,9 +92,10 @@ export const GraphiteQueryEditorContext = ({
// list of queries is passed only when the editor is in Dashboards. This is to allow interpolation
// of sub-queries which are stored in "targetFull" property used by alerting in the backend.
queries: queries || [],
refresh: (target: string) => {
onChange({ ...query, target: target });
onRunQuery();
refresh: () => {
// do not run onChange/onRunQuery straight away to ensure the internal state gets updated first
// to avoid race conditions (onChange could update props before the reducer action finishes)
setNeedsRefresh(true);
},
})
);

View File

@ -161,7 +161,7 @@ export function handleTargetChanged(state: GraphiteQueryEditorState): void {
);
if (state.queryModel.target.target !== oldTarget && !state.paused) {
state.refresh(state.target.target);
state.refresh();
}
}

View File

@ -25,7 +25,7 @@ export type GraphiteQueryEditorState = {
// external dependencies
datasource: GraphiteDatasource;
target: GraphiteTarget;
refresh: (target: string) => void;
refresh: () => void;
queries?: DataQuery[];
templateSrv: TemplateSrv;
range?: TimeRange;
@ -134,7 +134,7 @@ const reducer = async (action: Action, state: GraphiteQueryEditorState): Promise
}
if (actions.unpause.match(action)) {
state.paused = false;
state.refresh(state.target.target);
state.refresh();
}
if (actions.addFunction.match(action)) {
const newFunc = state.datasource.createFuncInstance(action.payload.name, {
@ -175,7 +175,7 @@ const reducer = async (action: Action, state: GraphiteQueryEditorState): Promise
handleTargetChanged(state);
}
if (actions.runQuery.match(action)) {
state.refresh(state.target.target);
state.refresh();
}
if (actions.toggleEditorMode.match(action)) {
state.target.textEditor = !state.target.textEditor;

View File

@ -77,5 +77,6 @@ export type GraphiteQueryEditorDependencies = {
range?: TimeRange;
templateSrv: TemplateSrv;
queries: DataQuery[];
refresh: (target: string) => void;
// schedule onChange/onRunQuery after the reducer actions finishes
refresh: () => void;
};