Загрузка аудиофайлов в базу данных Firebase Cloud, а затем повторное воспроизведение из базы данных для решения проблемы js + Endless l oop - PullRequest
1 голос
/ 09 февраля 2020

Я уже давно сталкиваюсь с этой проблемой, и она действительно стоит, мне нужна помощь. Заранее спасибо.

Следующий код должен быть формой, позволяющей легко добавлять новые документы в коллекцию базы данных облачного хранилища:

import React, {useState} from 'react';
import db from '../index';

const AddSongs = () => {
    const [song, setSong] = useState('');
    const [artist, setArtist] = useState('');
    const [src, setSrc] = useState('');


    const inSubmit = (e) =>{

        e.preventDefault();

        let songBase = db.collection('songs');
        let data = {song, artist, src}

        songBase
            .add(data)

    }


    return ( 
        <div>
            <form onSubmit={inSubmit}>
                <label>
                    Add Your Track
                </label>
                <input type="text" placeholder="Name of the track" value={song} onChange={e => 
                 setSong(e.target.value)} />
                <input type="text" placeholder="Name of the artist" value={artist} onChange={e => 
                 setArtist(e.target.value)} />
                <input type="file" value={src} onChange={e => setSrc(e.target.value)} />
                <div>
                    <input type="submit" value="add it" />
                </div>
            </form>
        </div>
    );
}

export default AddSongs;

И затем документы добавляются в облачную базу данных. успешно как обычные документы со свойствами / полями, такими как song, artist и sr c. И это еще один код, который должен затем взять текущие данные внутри коллекции и отобразить их в jsx div

import React, {useState} from 'react';
import db from '../index';

const SongList = () => {
    const [list, setList] = useState([])

    let songbase = db.collection('songs')

    songbase.onSnapshot(snapshot =>{
        snapshot.docs.forEach(doc =>{
            setList([...list, {song: doc.song, artist: doc.artist, src: doc.src, id: Math.random(0,1)}])
        })
    })

    const renderedList = list.length ? (list.map(songItem =>{
        return(
            <div key={songItem.id}>
                <span>{songItem.song}</span>
                <audio controls>
                    <source src={songItem.src} type="audio/mpeg" />
                </audio>
                <span>{songItem.artist}</span>
            </div>
        )
    })) : (<h1>nope !</h1>)


    return ( 
        <div>
            {renderedList}
        </div>
     );
}

export default SongList;

И затем, здесь происходит то, что songItem визуализируется внутри пустого jsx div, связанного с пустая звуковая метка внутри, и повторяется бесконечно и продолжает прокручиваться вниз! + поле sr c в БД, которое должно отображаться в звуковом теге, является просто строкой, а не ссылкой на реальный файл.

Мне просто нужно знать в этом случае, как добавить любой вид файлов в хранилище Firebase, а затем сослаться на эти файлы в базе данных, а затем отобразить файлы в обычном неповторяющемся div.

Большое спасибо.

1 Ответ

1 голос
/ 09 февраля 2020

Проблема в том, что вы обновляете свое состояние каждый раз, когда добавляете новый элемент в свой список.

Правильный код:

import React, { useState, useEffect } from 'react';
import db from '../index';

const SongList = () => {
  const [list, setList] = useState([]);

  useEffect(() => {
    const songbase = db.collection('songs');

    songbase.onSnapshot(snapshot => {
      const songList = [];

      snapshot.docs.forEach(doc => {
        const newSong = {
          song: doc.song,
          artist: doc.artist,
          src: doc.src,
          id: Math.random(0, 1)
        };

        songList.push(newSong);
      });

      setList(songList);
    });
  }, []);

  const renderedList = list.length ? (
    list.map(songItem => {
      return (
        <div key={songItem.id}>
          <span>{songItem.song}</span>
          <audio controls>
            <source src={songItem.src} type="audio/mpeg" />
          </audio>
          <span>{songItem.artist}</span>
        </div>
      );
    })
  ) : (
    <h1>nope !</h1>
  );

  return <div>{renderedList}</div>;
};

export default SongList;

Одна вещь, на которую стоит обратить внимание: нет нужно распространять список в новом массиве, потому что он всегда будет [], состояние по умолчанию для списка установлено в [].

Мы используем хук useEffect без зависимостей (пустой массив в качестве второго аргумента) , это выполнит код внутри ловушки при первом рендеринге компонента, и последующие отрисовки не выполнят код повторно. Это предотвратит бесконечное существование.

Дайте мне знать, если у вас есть какие-либо сомнения!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...