rusackas commented on code in PR #39460:
URL: https://github.com/apache/superset/pull/39460#discussion_r3278075843
##########
superset-frontend/src/dashboard/components/gridComponents/Markdown/Markdown.tsx:
##########
@@ -140,193 +132,200 @@ interface DragChildProps {
dragSourceRef: React.RefCallback<HTMLElement>;
}
-class Markdown extends PureComponent<MarkdownProps, MarkdownState> {
- renderStartTime: number;
-
- constructor(props: MarkdownProps) {
- super(props);
- this.state = {
- isFocused: false,
- markdownSource: props.component.meta.code as string,
- editor: null,
- editorMode: 'preview',
- undoLength: props.undoLength,
- redoLength: props.redoLength,
- };
- this.renderStartTime = Logger.getTimestamp();
-
- this.handleChangeFocus = this.handleChangeFocus.bind(this);
- this.handleChangeEditorMode = this.handleChangeEditorMode.bind(this);
- this.handleMarkdownChange = this.handleMarkdownChange.bind(this);
- this.handleDeleteComponent = this.handleDeleteComponent.bind(this);
- this.handleResizeStart = this.handleResizeStart.bind(this);
- this.setEditor = this.setEditor.bind(this);
- this.shouldFocusMarkdown = this.shouldFocusMarkdown.bind(this);
- }
-
- componentDidMount(): void {
- this.props.logEvent(LOG_ACTIONS_RENDER_CHART, {
- viz_type: 'markdown',
- start_offset: this.renderStartTime,
- ts: new Date().getTime(),
- duration: Logger.getTimestamp() - this.renderStartTime,
- });
- }
-
- static getDerivedStateFromProps(
- nextProps: MarkdownProps,
- state: MarkdownState,
- ): MarkdownState | null {
- const { hasError, editorMode, markdownSource, undoLength, redoLength } =
- state;
- const {
- component: nextComponent,
- undoLength: nextUndoLength,
- redoLength: nextRedoLength,
- } = nextProps;
- // user click undo or redo ?
- if (nextUndoLength !== undoLength || nextRedoLength !== redoLength) {
- return {
- ...state,
- undoLength: nextUndoLength,
- redoLength: nextRedoLength,
- markdownSource: nextComponent.meta.code as string,
- hasError: false,
- };
- }
+function Markdown({
+ id,
+ parentId,
+ component,
+ parentComponent,
+ index,
+ depth,
+ editMode,
+ availableColumnCount,
+ columnWidth,
+ onResizeStart,
+ onResize,
+ onResizeStop,
+ deleteComponent,
+ handleComponentDrop,
+ updateComponents,
+ logEvent,
+ addDangerToast,
+ undoLength,
+ redoLength,
+ htmlSanitization,
+ htmlSchemaOverrides,
+}: MarkdownProps) {
+ const [isFocused, setIsFocused] = useState(false);
+ const [markdownSource, setMarkdownSource] = useState<string>(
+ component.meta.code as string,
+ );
+ const [editor, setEditorState] = useState<EditorInstance | null>(null);
+ const [editorMode, setEditorMode] = useState<'preview' | 'edit'>('preview');
+ const [hasError, setHasError] = useState(false);
+
+ const renderStartTimeRef = useRef(Logger.getTimestamp());
+ const prevUndoLengthRef = useRef(undoLength);
+ const prevRedoLengthRef = useRef(redoLength);
+ const prevComponentWidthRef = useRef(component.meta.width);
+ const prevColumnWidthRef = useRef(columnWidth);
+
+ // getDerivedStateFromProps equivalent: handle undo/redo and external code
changes
+ useEffect(() => {
+ // user click undo or redo?
if (
+ undoLength !== prevUndoLengthRef.current ||
+ redoLength !== prevRedoLengthRef.current
+ ) {
+ setMarkdownSource(component.meta.code as string);
+ setHasError(false);
+ prevUndoLengthRef.current = undoLength;
+ prevRedoLengthRef.current = redoLength;
+ } else if (
!hasError &&
editorMode === 'preview' &&
- nextComponent.meta.code !== markdownSource
+ component.meta.code !== markdownSource
) {
- return {
- ...state,
- markdownSource: nextComponent.meta.code as string,
- };
+ setMarkdownSource(component.meta.code as string);
}
+ }, [
+ undoLength,
+ redoLength,
+ component.meta.code,
+ hasError,
+ editorMode,
+ markdownSource,
+ ]);
Review Comment:
Declining — the effect READS `markdownSource` at the conditional
(`component.meta.code !== markdownSource`) before deciding whether to set it.
Removing it from the deps array would freeze `markdownSource` at its initial
value, breaking the comparison after the first set. The set is guarded by
inequality so there's no infinite loop. The exhaustive-deps rule would also
flag the removal as incorrect. A cleaner refactor would track the previous code
with a ref, but that's a separate change outside this file's class→function
conversion scope.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]