Estoy usando react-native-sound para audio en este componente y quiero reproducir desde un archivo de URL que se pasa al componente. El problema es que si el var audio se declara dentro del componente funcional, cada vez que el componente representa, la variable se crea nuevamente y esto reproduce el archivo de sonido como una nueva instancia y tenemos el mismo sonido reproduciéndose varias veces uno encima del otro.
import Sound from "react-native-sound" var audio = new Sound.. //Works if declared here but cant's pass url prop const SoundPlayer: FC<SoundProps> = ({ url }) => { const [playing, setPlaying] = useState<boolean | null>(null) var audio = new Sound(url, null, (error) => { if (error) { console.log("failed to load the sound", error) return } }) Si muevo el audio var fuera/arriba del componente funcional como una variable global, funciona bien, pero luego no puedo pasarle la url del componente, ya que la variable está fuera del alcance del componente de la función. ¿Cómo puedo pasar un accesorio que mantiene la referencia y no se recrea en cada renderizado?
Intenta usar useEffect:
const audioRef = useRef(null); const [duration, setDuration] = useState(0); useEffect(() => { // This will be triggered only once when the component is mounted audioRef.current = new Sound(url, null, (error) => { if(error) { // Here you can implement some retry policy if there was some error loading the sound return; } setDuration(Math.trunc(audioRef.current.getDuration())); }); return = () => { // This will be triggered on component is unmounted audioRef.current.release(); } }, [audioRef, setDuration]);PD: este código se escribió sobre la marcha, por lo que es posible que se necesiten modificaciones adicionales
Este es el caso de uso correcto para useRef ( https://reactjs.org/docs/hooks-reference.html#useref )
import Sound from "react-native-sound" const SoundPlayer: FC<SoundProps> = ({ url }) => { const audioRef = useRef(null); const [playing, setPlaying] = useState<boolean | null>(null) // use useEffect to hook on mounted useEffect(() => { if(audioRef.current === null) { audioRef.current = new Sound(url, null, (error) => { if (error) { console.log("failed to load the sound", error) return } }) } }, [])Por ejemplo
import Sound from "react-native-sound" var audio; const SoundPlayer: FC<SoundProps> = ({ url }) => { const [playing, setPlaying] = useState<boolean | null>(null) useEffect(() => { audio = new Sound(url, null, (error) => { if (error) { console.log("failed to load the sound", error) return } }) }, [url]);