【问题标题】:Child not re-rendering in react孩子没有在反应中重新渲染
【发布时间】:2021-06-08 12:32:19
【问题描述】:

我正在编写一个用于播放不同音频文件的应用程序(循环播放)。在应用程序中,我希望多个文件能够同时播放,但它们需要从同一点开始。这意味着我激活的其他音轨只有在完成已播放的音频文件循环后才会开始播放。

我的组件目前是两个 -

  1. App.js(呈现不同的音频文件),父级。
  2. Play.js(提供播放和停止每个音频文件的选项),child。 一旦音频文件开始播放,我正在尝试将更新(通过钩子)传递给父级,但是每次进行此类更新时,我都会失去孩子的功能,即我可以开始播放文件但无法停止它。

这是我孩子的密码:

import React from 'react';


export function Play(props) {

 
 let currentlyPlaying = false;
 
 let audio = new Audio(props.audioClip.sound);
 const start = () => {
   console.log(currentlyPlaying);
   if (!currentlyPlaying) {
     props.onStart(); //problematic line, stops re-rendering of child
     audio.play()
     currentlyPlaying = true;
     audio.loop = true;
   }
 }

 const stop = () => {
   currentlyPlaying = false;
   audio.pause()
   audio.currentTime = 0;
 }


 return (
   <div>

     <p>Hear the sound of {props.audioClip.label}!: </p>
     <button onClick={start}  >Playyyy day</button>
     <button onClick={stop}>Stop me!</button>
   </div >
 );
}

export default Play

这是我父母的代码:

function App () {
    const [counter, setCounter] = useState(0);
    // const [playingAnySong, setPlaying] = useState(false);
    const [audioClips, setAudioClips] = useState([
      { sound: Bass, label: 'Funky Bass', playing: false },
      { sound: futureFunk, label: 'Future Funk', playing: false },
      { sound: stutterBeats, label: 'Stuttering Beats', playing: false },
      { sound: electricGuitar, label: 'Electric country guitar', playing: false },
      { sound: StompySlosh, label: 'Stompin rythm', playing: false },
      { sound: groove, label: 'Groovyyy', playing: false },
      { sound: MazePolitics, label: 'The Maze', playing: false },
      { sound: pas3, label: 'Sachi drums', playing: false },
      { sound: organSynth, label: 'Psychedelic Organ', playing: false },
    ])


    return (
      <div className="container">
        {audioClips.map((audio, i) => {
          return <Play key={i} onStart={value => setCounter(counter + 1)} audioClip = {audio} />
        })}
      </div>
    );
  }




export default App;

我感觉我在为父级更新状态方面做错了。 您能否确定为什么每次我更新父级时我的应用程序都会停止运行?

【问题讨论】:

  • 为什么会有这行代码onStart={value =&gt; setCounter(counter + 1)}
  • 这是一个错误。我想将更新父母状态以计算活动音频文件数量的能力传递给孩子(更新“计数器”的能力)。

标签: reactjs react-hooks


【解决方案1】:

在您的播放组件中使用当前播放和音频的状态。

import React, {FC, useState} from 'react';


export const Play: FC <any> = ({audioClip, onStart}) => {

 const [currentlyPlaying, setCurrentlyPlaying] = useState(false)
 const [audio] = useState(new Audio(audioClip.sound)) // to keep track of the audio of the component

 const start = () => {
   console.log(currentlyPlaying);
   if (!currentlyPlaying) {
     onStart(); //problematic line, stops re-rendering of child
     audio.play()
     audio.loop = true;
     setCurrentlyPlaying(true)
   }
 }

 const stop = () => {
   setCurrentlyPlaying(false);
   audio.pause();
   audio.currentTime = 0;
 }

 return (
   <div>
     <p>Hear the sound of {audioClip.label}!: </p>
     <button onClick={start}  >Playyyy day</button>
     <button onClick={stop}>Stop me!</button>
   </div >
 );
}

export default Play

在您的 App 组件中,为 onStart 属性声明一个函数,因为您当前的代码使播放组件在每次 App 组件中有更新时重新呈现。

function App () {
const [counter, setCounter] = useState(0);
// const [playingAnySong, setPlaying] = useState(false);
const [audioClips, setAudioClips] = useState([
  { sound: Bass, label: 'Funky Bass', playing: false },
  { sound: futureFunk, label: 'Future Funk', playing: false },
  { sound: stutterBeats, label: 'Stuttering Beats', playing: false },
  { sound: electricGuitar, label: 'Electric country guitar', playing: false },
  { sound: StompySlosh, label: 'Stompin rythm', playing: false },
  { sound: groove, label: 'Groovyyy', playing: false },
  { sound: MazePolitics, label: 'The Maze', playing: false },
  { sound: pas3, label: 'Sachi drums', playing: false },
  { sound: organSynth, label: 'Psychedelic Organ', playing: false },
])
const handleStart = value => setCounter(counter + 1)


return (
  <div className="container">
    {audioClips.map((audio, i) => {
      return <Play key={i} onStart={handleStart} audioClip = {audio} />
    })}
  </div>
);

}

export default App;

【讨论】:

  • 您能否告诉我“为 onStart 道具声明一个函数,因为您当前的代码使播放组件在每次 App 组件中有更新时重新呈现。”是什么意思?我为当前播放添加了一个状态:export function Play(props) { const [currentlyPlaying, setCurrentlyPlaying] = useState(false);
  • 首先,谢谢伙计!我添加了您建议我添加的功能,但不幸的是我仍然遇到同样的问题 - 我对子组件中的状态(父状态和子状态)所做的每次更新都会阻止我的代码并停止其功能(我无法停止曲目一旦开始)。
  • 如果你评论了audio.loop,你还有问题吗?
  • 你能说明声音是什么物体吗?
  • 删除了音频循环,我递归地调用 start()。还是有问题。
猜你喜欢
  • 2016-05-17
  • 1970-01-01
  • 1970-01-01
  • 2017-08-28
  • 2019-11-02
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 2021-08-22
相关资源
最近更新 更多