You need to enable JavaScript to run this app. React结合Tone.js场景下更新状态不触发组件整体重渲染的方案问询
优惠活动
大模型
产品
解决方案
定价
更多

React结合Tone.js场景下更新状态不触发组件整体重渲染的方案问询

React 结合 Tone.js 重渲染导致实例丢失问题
  • 我开发了一个React组件,该组件实例化了Tone.js库的若干类(例如音频播放器、滤波器),同时定义了若干作用于这些对象的函数,这些函数会作为回调绑定到一组UI渲染的按钮上(相关代码见下文)。
  • 现有两个按钮需要通过updateSpatial函数中实现的useState Hook切换布尔状态is3D,以此来启用/禁用其中一个按钮。但该状态更新操作会触发组件整体重渲染,导致之前实例化的类被重新创建,后续定义的功能函数将无法正常工作。
  • 我也尝试过使用useRef Hook,这种方式可以更新is3D的值而不触发重渲染,但由于组件没有重新渲染,按钮的disabled状态无法同步更新。
  • 请问该场景下有没有适配的设计模式?我后续计划尝试使用HOC、Context或者Redux,但不确定这类方案是否为最直接的实现路径,恳请指点。
import React, {useState, useEffect, Fragment} from 'react'
import { Player, Destination} from "tone";

const Eagles = () => {

  const [is3D, setIs3D] = useState(false);

  useEffect(() => {
    // connect players to destination, ready to play
    connectBase();
  });
  
  // Instantiating players
  const player1= new Player({
    "url": "https://[你的S3存储桶域名]/Aguabeber.m4a",
    "autostart": false,
    "onload": console.log("player 1 ready")    
  });
  const player2 = new Player({
    "url": "https://[你的S3存储桶域名]/Aguas.m4a",
    "autostart": false,
    "onload": console.log("player 2 ready")
  });             
  // Functions
  function connectBase() {
    player1.disconnect();
    player1.connect(Destination);
    player2.disconnect();    
    player2.chain(Destination);
  }
  function playStudio() {
    player1.volume.value = 0;
    player2.volume.value = -60;    
  }
  function playCinema() {
    player1.volume.value = -60;
    player2.volume.value = 0;  
  }
  function  playstereo() {
    player1.volume.value = 0;
    player2.volume.value = -60;
    updateSpatial();
  }  
  function  playmyhifi() {
    player1.volume.value = -60;
    player2.volume.value = 0;
    updateSpatial();
  }  
  function start() {
      player1.start();
      player2.start();      
      playstereo();
    }  
  function stop() {
    player1.stop();
    player2.stop();      
    console.log("stop pressed")
  }
  // Update state to toggle button enabled  
  function updateSpatial() {
    setIs3D((is3D) => !is3D);
  }

  return (
    <Fragment>       
          <ButtonTL onClick={start}>Play</ButtonTL>
          <ButtonTR onClick={stop}>Stop</ButtonTR>     
          <ButtonTL2 onClick={playstereo}>Stereo</ButtonTL2>
          <ButtonTR2 onClick={playmyhifi}>3D</ButtonTR2>             
          <ButtonLL disabled={is3D} onClick={playStudio}>Studio</ButtonLL>
          <ButtonLR onClick={playCinema}>Cinema</ButtonLR>                                                          
     </Fragment>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 23:27:03