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

React组件调用外部anime.js动画函数出现不可达代码及DOM为空问题

问题原因

  • render方法中return语句后的代码永远不会被执行,JavaScript执行到return就会跳出当前函数,因此写在return后的letterStagger()属于不可达代码,触发对应警告。
  • 若在DOM未完成挂载时调用动画函数,document.querySelector无法匹配到还未渲染到页面的元素,会返回null,操作null的textContent属性自然会触发报错。

解决方法

类组件的componentDidMount生命周期钩子会在组件首次挂载到真实DOM之后触发,此时对应元素已经完成渲染,直接在这个钩子中调用动画函数即可。

基础修复代码

import React from 'react';
import { letterStagger } from "../../utils/animations";

class Hero extends React.Component{
  // 组件挂载完成后执行动画
  componentDidMount() {
    letterStagger();
  }

  render(){
    return (
      <section className="hero">
        <h1 className="hero__title">
          <span className="hero__title-inner">
            <span className="hero__title-letters">This is the title</span>
          </span>
        </h1>
      </section>
    )
  }
}

export default Hero;

优化方案(推荐)

为了避免全局document.querySelector在页面存在多个Hero组件时出现匹配冲突,可以使用React的ref直接传递目标DOM元素给动画函数:

  1. 修改animations.js,改为接收目标元素作为参数:
import anime from 'animejs/lib/anime.es.js';

export function letterStagger(textWrapper){
  textWrapper.innerHTML = textWrapper.textContent.replace(/\S/g, "<span class='hero__title-letter'>$&</span>");

  anime.timeline({loop: true})
  .add({
    targets: textWrapper.querySelectorAll('.hero__title-letter'),
    translateY: ["1.1em", 0],
    translateZ: 0,
    duration: 750,
    delay: (el, i) => 50 * i
  }).add({
    targets: textWrapper.closest('.hero__title'),
    opacity: 0,
    duration: 1000,
    easing: "easeOutExpo",
    delay: 1000
  });
}
  1. 修改Hero组件,通过ref传递元素:
import React from 'react';
import { letterStagger } from "../../utils/animations";

class Hero extends React.Component{
  constructor(props) {
    super(props);
    // 创建ref引用
    this.titleLetterRef = React.createRef();
  }

  componentDidMount() {
    // 把获取到的DOM元素传给动画函数
    letterStagger(this.titleLetterRef.current);
  }

  render(){
    return (
      <section className="hero">
        <h1 className="hero__title">
          <span className="hero__title-inner">
            {/* 绑定ref到目标元素 */}
            <span ref={this.titleLetterRef} className="hero__title-letters">This is the title</span>
          </span>
        </h1>
      </section>
    )
  }
}

export default Hero;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:39:03