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

如何让React组件的OnLoad事件生效?实现组件加载后单次调用函数

解决React组件加载后仅调用一次函数的问题

问题原因分析

  1. 直接在组件函数内调用handleClick()会触发无限循环:组件渲染时执行该函数,函数内的setDisabled、setHighlightSection会触发组件重新渲染,重新渲染又会再次调用handleClick,陷入循环。
  2. <div>的onLoad事件无效:该事件仅适用于<img>、<script>等需要加载外部资源的元素,普通<div>不会触发此事件。

解决方案:使用useEffect钩子

React的useEffect钩子可用于在组件挂载、更新或卸载阶段执行副作用操作。通过设置空依赖数组,能让回调函数仅在组件首次挂载(加载完成)时执行一次。

修改后的代码示例

function BadgeSample(props) {
    const {
      type,
      defaultValue,
      className,
      style,
      value,
      bootstrapStyle,
      clickable,
      onClickAction,
      getRef
    } = props;
    const [disabled, setDisabled] = React.useState(false);
    const [pasuedd, setPasued] = React.useState(false);
    const [highlightSection, setHighlightSection] = React.useState({
      from: 0,
      to: 0
    });
    const synth = window.speechSynthesis;
    let utterance;
    const handleClick = () => {
      if (!synth) {
        console.error("no tts");
        return;
      }
      utterance = new SpeechSynthesisUtterance(value || defaultValue);
      utterance.addEventListener("start", () => setDisabled(true));
      utterance.addEventListener("end", () => setDisabled(false));
      utterance.addEventListener("boundary", ({
        charIndex,
        charLength
      }) => {
        setHighlightSection({
          from: charIndex,
          to: charIndex + charLength
        });
      });
      synth.speak(utterance);
    };
    const stoped = () => {
      synth.cancel(utterance);
    };
    const pasued = () => {
      setPasued(true);
      synth.pause(utterance);
    };
    const resumed = () => {
      setPasued(false);
      synth.resume(utterance);
    };

    // 组件挂载后仅执行一次handleClick
    React.useEffect(() => {
        handleClick();
    }, []); // 空数组表示仅在组件挂载阶段执行

    return React.createElement("div", {
      className: "App",
      onClick: onClickAction,
      ref: getRef,
      style: style
    }, React.createElement(HighlightedText, _extends$sj({
      text: value || defaultValue
    }, highlightSection)), React.createElement("button", {
      className: disabled ? "stopbtn" : "playbtn",
      onClick: disabled ? stoped : handleClick
    }, disabled ? React.createElement("div", null, React.createElement(StopCircleFill, null), "Stop") : React.createElement("div", null, React.createElement(PlayCircleFill, null), "Listen")), disabled ? React.createElement("button", {
      className: pasuedd ? "playbtn" : "pausebtn",
      onClick: pasuedd ? resumed : pasued
    }, pasuedd ? React.createElement("div", null, React.createElement(PlayCircleFill, null), "Resume") : React.createElement("div", null, React.createElement(PauseCircleFill, null), "Pause")) : "");
  }

补充说明

如果handleClick依赖于组件的props或state(比如value、defaultValue),需要把这些依赖项加入到useEffect的依赖数组中,确保依赖变化时能正确执行。若想避免handleClick每次渲染都重新创建,可使用useCallback包裹:

const handleClick = React.useCallback(() => {
  // 原handleClick代码逻辑
}, [value, defaultValue, synth]);

React.useEffect(() => {
  handleClick();
}, [handleClick]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:05:19