You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何修改updateTrigger无法触发EditorBasic的componentDidUpdate?

问题原因与解决方案

1. componentDidUpdate未触发的核心原因

当你点击"Click to toggle EditorBasic"时,组件的生命周期逻辑是:

  • 首次点击:showEditorBasic从false变为true,EditorBasic是首次挂载,只会执行componentDidMount,不会触发componentDidUpdate
  • 第二次点击:showEditorBasic变为false,组件被完全卸载
  • 后续点击:每次都是重新挂载/卸载组件,永远不会进入更新生命周期

updateTrigger的变化只有在组件已挂载的前提下才会触发componentDidUpdate,但你的逻辑通过showEditorBasic控制组件的挂载与卸载,导致这个prop的变化永远无法被组件的更新钩子捕获。

2. 组件高度获取的误区

你的aRef指向的是包裹EditorBasic的外层<div>,而非EditorBasic组件内部的元素。如果要获取组件自身的高度,需要直接给组件内部的根元素添加ref。

修复后的代码示例

App.tsx 修改

import * as React from 'react';
import EditorBasic from './EditorBasic';

interface IAppProps {}

interface IAppState {
  showEditorBasic: boolean;
  updateTrigger: number;
}

export default class App extends React.Component<IAppProps, IAppState> {
  aRef: React.RefObject<HTMLDivElement>;
  editorRef: React.RefObject<EditorBasic>;

  constructor(props) {
    super(props);
    this.state = {
      showEditorBasic: false,
      updateTrigger: 0,
    };
    this.aRef = React.createRef();
    this.editorRef = React.createRef();
  }

  calculateNextHeight = () => {
    console.log('外层包裹div高度', this.aRef.current?.clientHeight);
    // 调用EditorBasic暴露的方法获取内部高度
    console.log('EditorBasic内部高度', this.editorRef.current?.getInnerHeight());
  };

  toggleEditor = () => {
    this.setState(prev => ({
      showEditorBasic: !prev.showEditorBasic,
      updateTrigger: prev.updateTrigger + 1,
    }), () => {
      // 组件挂载完成后主动触发高度计算
      if (this.state.showEditorBasic) {
        this.calculateNextHeight();
      }
    });
  };

  render() {
    return (
      <div>
        <div onClick={this.toggleEditor}>
          Click to toggle EditorBasic
        </div>
        {this.state.showEditorBasic && (
          <div ref={this.aRef}>
            <EditorBasic
              ref={this.editorRef}
              calculateNextHeight={this.calculateNextHeight}
              updateTrigger={this.state.updateTrigger}
            />
          </div>
        )}
      </div>
    );
  }
}

EditorBasic.tsx 修改

import * as React from 'react';

interface IEditorBasicProps {
  calculateNextHeight: () => void;
  updateTrigger: number;
}

interface IEditorBasicState {}

export default class EditorBasic extends React.Component<
  IEditorBasicProps,
  IEditorBasicState
> {
  innerRef: React.RefObject<HTMLDivElement>;

  constructor(props) {
    super(props);
    this.innerRef = React.createRef();
  }

  handleResize = () => {
    this.props.calculateNextHeight();
  };

  // 暴露给父组件获取内部高度的方法
  getInnerHeight = () => {
    return this.innerRef.current?.clientHeight;
  };

  componentDidMount() {
    window.addEventListener('resize', this.handleResize);
    // 挂载完成后立即计算一次高度
    this.handleResize();
  }

  componentDidUpdate(prevProps) {
    if (this.props.updateTrigger !== prevProps.updateTrigger) {
      this.handleResize();
    }
  }

  componentWillUnmount() {
    // 移除监听避免内存泄漏
    window.removeEventListener('resize', this.handleResize);
  }

  render() {
    return (
      <div ref={this.innerRef}>
        <br />
        <br />
        EditorBasic {this.props.updateTrigger}
        <br />
        <br />
      </div>
    );
  }
}

关键修复点

  • 给EditorBasic内部根元素添加ref,确保获取的是组件自身的高度
  • 在父组件setState的回调中,组件挂载完成后主动触发高度计算
  • 新增componentWillUnmount移除resize监听,避免内存泄漏
  • 如果需要通过updateTrigger触发组件更新,需保证组件始终处于挂载状态(比如用CSS隐藏替代卸载)

内容的提问来源于stack exchange,提问作者SoftTimur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 14:16:24