Optimisations to try and lower the number of rerenders required when switching tasks
This commit is contained in:
parent
f530fc7efa
commit
bde4247e29
@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from "react";
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import {
|
||||
TaskDefinition,
|
||||
TaskMetadata,
|
||||
@ -14,7 +14,7 @@ interface TaskEditorProps {
|
||||
onValidate: (taskId: string, isValid: boolean) => void;
|
||||
}
|
||||
|
||||
export const TaskEditor: React.FC<TaskEditorProps> = ({
|
||||
const TaskEditorComponent: React.FC<TaskEditorProps> = ({
|
||||
task,
|
||||
tasks,
|
||||
tasksMetadata,
|
||||
@ -41,23 +41,34 @@ export const TaskEditor: React.FC<TaskEditorProps> = ({
|
||||
[onValidate],
|
||||
);
|
||||
|
||||
const tasksRef = React.useRef(tasks);
|
||||
React.useEffect(() => {
|
||||
runValidation(task, tasks, tasksMetadata);
|
||||
}, [task.config.guid, runValidation]);
|
||||
tasksRef.current = tasks;
|
||||
}, [tasks]);
|
||||
|
||||
const handleTaskChange = (updatedTask: TaskDefinition) => {
|
||||
// Update the task list
|
||||
const updatedTasks = tasks.map((t) =>
|
||||
t.config.guid === updatedTask.config.guid ? updatedTask : t,
|
||||
);
|
||||
React.useEffect(() => {
|
||||
runValidation(task, tasksRef.current, tasksMetadata);
|
||||
}, [task.config.guid, runValidation, tasksMetadata]);
|
||||
|
||||
runValidation(updatedTask, updatedTasks, tasksMetadata);
|
||||
const handleTaskChange = useCallback(
|
||||
(updatedTask: TaskDefinition) => {
|
||||
// Update the task list
|
||||
const updatedTasks = tasks.map((t) =>
|
||||
t.config.guid === updatedTask.config.guid ? updatedTask : t,
|
||||
);
|
||||
|
||||
// Bubble updated task up
|
||||
onChange(updatedTask);
|
||||
};
|
||||
runValidation(updatedTask, updatedTasks, tasksMetadata);
|
||||
|
||||
const taskMeta = tasksMetadata.find((t) => t.taskType === task.type);
|
||||
// Bubble updated task up
|
||||
onChange(updatedTask);
|
||||
},
|
||||
[tasks, tasksMetadata, runValidation, onChange],
|
||||
);
|
||||
|
||||
const taskMeta = useMemo(
|
||||
() => tasksMetadata.find((t) => t.taskType === task.type),
|
||||
[tasksMetadata, task.type],
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -83,3 +94,22 @@ export const TaskEditor: React.FC<TaskEditorProps> = ({
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const TaskEditor = React.memo(
|
||||
TaskEditorComponent,
|
||||
(prevProps, nextProps) => {
|
||||
const taskIdChanged =
|
||||
prevProps.task.config.guid !== nextProps.task.config.guid;
|
||||
const metaChanged = prevProps.tasksMetadata !== nextProps.tasksMetadata;
|
||||
const onChangeChanged = prevProps.onChange !== nextProps.onChange;
|
||||
const onValidateChanged = prevProps.onValidate !== nextProps.onValidate;
|
||||
|
||||
// Skip tasks comparison - we use a ref to access it
|
||||
return !(
|
||||
taskIdChanged ||
|
||||
metaChanged ||
|
||||
onChangeChanged ||
|
||||
onValidateChanged
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import templateVersionsService, {
|
||||
CreateWorkflowTemplateVersion,
|
||||
TaskDefinition,
|
||||
@ -60,10 +60,31 @@ const TasksTab: React.FC<TasksTabProps> = ({
|
||||
setSelectedTask(tasks[0]);
|
||||
}, [tasks, taskValidation, selectedTask]);
|
||||
|
||||
const handleTasksChange = (newTasks: TaskDefinition[]) => {
|
||||
// Update the parent form state
|
||||
onTasksChange("tasks", newTasks);
|
||||
};
|
||||
const handleTasksChange = React.useCallback(
|
||||
(newTasks: TaskDefinition[]) => {
|
||||
// Update the parent form state
|
||||
onTasksChange("tasks", newTasks);
|
||||
},
|
||||
[onTasksChange],
|
||||
);
|
||||
|
||||
const handleTaskEditorChange = React.useCallback(
|
||||
(updatedTask: TaskDefinition) => {
|
||||
const newTasks = tasks.map((t) =>
|
||||
t.config.guid === updatedTask.config.guid ? updatedTask : t,
|
||||
);
|
||||
|
||||
handleTasksChange(newTasks);
|
||||
|
||||
// Use the updated object from the array, not the raw updatedTask
|
||||
const updatedFromArray = newTasks.find(
|
||||
(t) => t.config.guid === updatedTask.config.guid,
|
||||
);
|
||||
|
||||
setSelectedTask(updatedFromArray!);
|
||||
},
|
||||
[tasks, handleTasksChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="two-column-grid no-scroll">
|
||||
@ -84,20 +105,7 @@ const TasksTab: React.FC<TasksTabProps> = ({
|
||||
tasksMetadata={tasksMetadata}
|
||||
task={selectedTask}
|
||||
tasks={tasks}
|
||||
onChange={(updatedTask) => {
|
||||
const newTasks = tasks.map((t) =>
|
||||
t.config.guid === updatedTask.config.guid ? updatedTask : t,
|
||||
);
|
||||
|
||||
handleTasksChange(newTasks);
|
||||
|
||||
// Use the updated object from the array, not the raw updatedTask
|
||||
const updatedFromArray = newTasks.find(
|
||||
(t) => t.config.guid === updatedTask.config.guid,
|
||||
);
|
||||
|
||||
setSelectedTask(updatedFromArray!);
|
||||
}}
|
||||
onChange={handleTaskEditorChange}
|
||||
onValidate={onValidate}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user