将音频文件上传到Firebase Cloud数据库,然后将其从数据库重新转换为React js + Endless Lo



我已经面临这个问题有一段时间了,它真的很麻烦,我需要帮助。提前谢谢。

以下代码应该是一个表单,可以在 firestore 云数据库集合中轻松添加新文档:

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;

然后,文档作为普通文档成功添加到云数据库中,其属性/字段是歌曲、艺术家和 src。 这是另一个代码,然后应该获取集合中的当前数据并将其呈现为 jsxdiv

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 在一个包含空音频标签的空 jsxdiv 中渲染,并无休止地重复自己并不断向下滚动..... ! + 数据库中应该在音频标签中呈现的 src 字段只是一个字符串,而不是对真实文件的引用。

在这种情况下,我只需要知道如何将任何类型的文件添加到 firebase 存储中,然后在数据库中引用这些文件,然后在正常的非重复div 中渲染这些文件。

多谢。

这里的问题是每次向列表中添加新元素时都会更新状态。

正确的代码:

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钩子(空数组作为第二个参数(,这将在组件第一次呈现时执行钩子内的代码,后续渲染它不会重新运行代码。这将防止您拥有的无限循环。

如果您有任何疑问,请告诉我!

最新更新