You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js中如何动态匹配数据库数据加载对应音频文件

动态匹配数据库数据播放音频文件的解决方案

问题背景

需要基于数据库返回的数据数组,从文件夹中动态匹配并加载音频文件,但手动导入固定文件名的方式无法满足动态匹配需求,因此要实现遍历数据数组、自动匹配对应音频的功能。

修复后的完整代码

将音频文件移至public目录,并修复audioPlay函数后,实现了动态匹配功能,完整代码如下:

import axios from 'axios'
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router'
import api from '../../../Api'
import Carregando from '../../../components/Carregando'
import OffCanvas from '../../../components/OffCanvas'

const audioFilesContext = require.context(
  '../../../../public/audios/listening-reading',
  true,
  /\.mp3$/
);

const ListeningReading = () => {
  const [play, setPlay] = useState('')

  const location = useLocation()
  const conteudoAtual = {
    nivel: location.state.nivel,
    aula:  location.state.aula
  }

  const [posts, setPosts] = useState([])
  const [loading, setLoading] = useState(false)

  useEffect(() =>{
    const fetchPost = async () =>{
      setLoading(true)
      await axios.post(`${api}/listening-reading`,{
        nivel: conteudoAtual.nivel,
        aula: conteudoAtual.aula,
      }).then((response) => { 
        console.log('response')
        setPosts(response.data)
      }).catch((rejected)=> { console.error(rejected.response.data)})
      setLoading(false)
    }
    fetchPost()
  },[conteudoAtual.nivel, conteudoAtual.aula])

  const audioPlay = async () =>{
    await posts.map((post) => {
      const path = audioFilesContext.keys().find((key) => key.replace('./', '') === post.audio)
      const audioFile = path ? `../../../../public/audios/listening-reading/${path.replace('./', '')}` : null
      const audioCut = audioFile.replace('../../../../public', '')

      setPlay(audioCut)
    })
  }
  
  if(play === ''){audioPlay()}
  

  return (
    <>
      <OffCanvas/>
      <br/>
      <div className='container mt-5'>
        <h1>Listening Reading</h1>
        {
          posts.map((post) =>(
            <div key={post.id}>
              <h3>{post.titulo}</h3>
              <p className="fw-semibold">{post.texto}</p>
              <audio controls>
                <source 
                  src={play}              
                  type="audio/mp3"
                  />
                Your browser does not support the audio element.
              </audio>
            </div>
          ))
        }
        {loading && <Carregando/>}
      </div>
    </>
  )
}

export default ListeningReading

此前的固定导入方式(仅支持静态文件名)

这两种方式只能加载固定文件名的音频,无法实现动态匹配:

  • 手动ES6导入:
    import listenToAudio from '../../../audios/listening-reading/hello.mp3'
    
  • 使用require导入:
    const listenToAudio = require('../../../audios/listening-reading/hello.mp3')
    

动态匹配音频的有效实现

现在通过遍历数据库返回的posts数组,每个条目都能匹配到对应的音频文件并播放,核心渲染代码如下:

{
  posts.map((post) =>(
    <div key={post.id}>
      <h3>{post.titulo}</h3>
      <p className="fw-semibold">{post.texto}</p>
      <audio controls>
        <source 
          src={play}              
          type="audio/mp3"
          />
        Your browser does not support the audio element.
      </audio>
    </div>
  ))
}

内容的提问来源于stack exchange,提问作者Felipe Teixeira Schefer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 16:10:23