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

React根据用户输入动态获取Firestore视频字段的实现问题

问题描述

正在开发用于展示龙与地下城(DnD)动态视频地图的React应用,用户通过下拉选择框完成选项选择后,视频播放器需要从存储视频资源的Firebase Firestore数据库拉取对应视频文件播放。
现有代码如下:

const Streamplayer = ({vidSelection}) => { //vidSelection是下拉选择框返回的字符串类型选中值
const [links, setLinks] =  useState([])

console.log(vidSelection);
useEffect(() => {
   getLinks()
}, [])

useEffect(() => {
   console.log(links)
}, [links])

function getLinks(){
   const vidRef = collection(db, 'links');
   getDocs(vidRef).then(response => {
      console.log(response.docs)
      const lnks = response.docs.map(doc => ({
         data: doc.data(), 
         id: doc.id,
      }))
      setLinks(lnks)
   }).catch(error => console.log(error.message));
}

function getVid(){
   const toReturn = links.map((link) => link.data.vidSelection);//这里需要根据输入动态返回对应字段
   console.log(toReturn)
   return toReturn;
}

return (    
<video
controls={false}
autoPlay
muted
loop
className="Video"
key={getVid()}
>
<source src={getVid()} type="video/mp4" />
</video>
)
}

export default Streamplayer

当前getVid()方法的逻辑无法正常工作:需要读取Firestorelinks集合存储的数据,根据用户选中值动态返回对应字段——比如用户选择名为"Grotto"的地图时,需要读取link.data.grotto字段的视频地址,但vidSelection是字符串变量,无法直接通过点语法嵌入属性访问路径。

解决方法

JS中如果要通过字符串变量访问对象属性,不能用点语法,直接换方括号取值语法就行:对象[存属性名的变量]。比如vidSelection的值是字符串"Grotto"时,link.data[vidSelection]就完全等价于link.data.grotto,这就是需要的动态属性读取效果。

另外原有代码还有几个逻辑bug要一起修正:

  • getVid()里用map返回的是数组,video标签的src只接收单个字符串地址,传数组会播放失败
  • 数据还没拉取完成、或者选中项没有对应地址时要做兜底,避免空值报错
  • 视频的key直接绑定当前播放地址就行,地址变化时会自动触发视频重新加载,不需要反复调用getVid()

修正后的可运行代码:

import { useState, useEffect, useMemo } from 'react'
import { collection, getDocs } from 'firebase/firestore'
import { db } from './your-firebase-config-path' // 替换为你自己的Firebase配置引入路径

const Streamplayer = ({vidSelection}) => { 
  const [links, setLinks] = useState([])
  
  // 组件挂载时拉取一次所有视频地址配置
  useEffect(() => {
    const vidRef = collection(db, 'links');
    getDocs(vidRef).then(response => {
      const lnks = response.docs.map(doc => ({
        data: doc.data(), 
        id: doc.id,
      }))
      setLinks(lnks)
    }).catch(error => console.log(error.message));
  }, [])

  // 计算当前要播放的视频地址,依赖links和选中值自动更新
  const currentVidSrc = useMemo(() => {
    if (!links.length) return ''
    // 若links集合只有一条存全量地图地址的配置文档,直接取第一条即可
    const linkConfig = links[0].data
    // 用方括号语法读取变量对应的属性,无匹配时返回空
    return linkConfig[vidSelection] || ''
  }, [links, vidSelection])

  // 地址未加载完成时返回兜底提示
  if (!currentVidSrc) return <div>视频加载中...</div>

  return (    
    <video
      controls={false}
      autoPlay
      muted
      loop
      className="Video"
      key={currentVidSrc}
    >
      <source src={currentVidSrc} type="video/mp4" />
    </video>
  )
}

export default Streamplayer

如果你的links集合是每个地图存一条独立文档,只需要调整currentVidSrc的查找逻辑即可,核心的动态属性访问还是用方括号语法。

内容的提问来源于stack exchange,提问作者Meli497

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:42:22