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

This commit is contained in:
Piotr Jamróz
2021-11-24 14:08:00 +01:00
committed by GitHub
parent 09c849eb08
commit b3e417f768
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;
};