【问题标题】:How to properly store data from Firebase Realtime Database and render it with React once it has been retrieved?如何正确存储 Firebase 实时数据库中的数据并在检索到数据后使用 React 进行渲染?
【发布时间】:2021-11-23 17:32:06
【问题描述】:

我正在成功地从我的 Firebase 实时数据库中检索数据,但我无法使用 React 将其存储并呈现到我的网页上。谁能告诉我我的流程目前有什么问题?和/或您能否分享一个类似用例中“正确”存储/渲染过程的示例?

这是我渲染存储数据的方式:

function Dashboard() {

var player_data;
var name_string;

return (
    <div className="dashboard">
        <h2>{player_data && player_data.settlement.settlement_name}</h2> {/* NOT RENDERING */}
    </div>

  );

这里是获取 player_data 的函数,它正在成功地将数据写入控制台:

function GetPlayerData(){       
Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
        if (snapshot.exists()) {
            console.log(snapshot.val());
            player_data = snapshot.val();
            console.log(player_data.settlement.settlement_name)
            console.log(player_data.player_data.ancestor_name)
            name_string = JSON.stringify(player_data.settlement.settlement_name)
        } else {
            console.log("No data available");
        }
        }).catch((error) => {
        console.error(error);
        });
    }

非常感谢!

下一次尝试:我尝试将带有 useState 的 player_data 存储为 const JSON 变量,如下所示,结果收到“TypeError: Cannot read properties of undefined (reading 'settlement_name') "

function Dashboard() {
const [ player_data, setPlayerData ] = useState();

return (
    <div className="dashboard">
        <h2>{player_data && player_data.settlement.settlement_name}</h2> {/* NOT RENDERING */}
        <h2>{player_data && player_data.player_data.ancestor_name}</h2> {/* NOT RENDERING */}
    </div>

这是我更新后的 GetPlayerData():

Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
        if (snapshot.exists()) {
            console.log(snapshot.val());
            setPlayerData(snapshot.val());
            console.log(player_data.settlement.settlement_name)
            console.log(player_data.player_data.ancestor_name)
        } else {
            console.log("No data available");
        }
        }).catch((error) => {
        console.error(error);
        });
    }

  );

这是我的数据库当前结构的屏幕截图:

热烈感谢任何建议。谢谢阅读! :)

工作代码!

function Dashboard() {
const [ playerData, setPlayerData ] = useState();

return (
    <div className="dashboard">
        <h2>{playerData && playerData.settlement.settlement_name}</h2> {/* RENDERING!! */}
        <h2>{playerData && playerData.player_data.ancestor_name}</h2> {/* RENDERING! */}
    </div>

这是我更新后的 GetPlayerData():

Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
        if (snapshot.exists()) {
            console.log(snapshot.val());
            setPlayerData(snapshot.val());
            console.log(playerData) {/* NOT LOGGING : RETURNING UNDEFINED */}            
            console.log(playerData.settlement.settlement_name) {/* NOT LOGGING : RETURNING TypeError: Cannot read properties of undefined (reading 'settlement') */}
        } else {
            console.log("No data available");
        }
        }).catch((error) => {
        console.error(error);
        });
    }

  );

【问题讨论】:

    标签: javascript reactjs firebase firebase-realtime-database


    【解决方案1】:

    您可以使用 firebase API 从 firebase 实时数据库中获取数据并将其存储在 state 或 redux 存储中。使用 useEffect 调用异步函数。

    const getData=async ()=>{
      const response=await fetch('firebase API url');
      const data=await response.json();
      setPlayerData(data)
     }
    useEffect(()=>{
     getData()
    },[]);
    

    为了将数据渲染到 JSX,请告诉我您从 firebase 检索的数据类型。您是返回对象还是对象数组?

    根据返回值,我们应该在 JSX 中编写代码。

    如果你要返回一个对象:

    const playerdata={name:'Roomba',settlement:{settlement_name:'RumCity'}}
    JSX Code:
    <div>
    <h1>{playerData.name} {playerData.settlement.settlement_name}</h1>
    

    如果您来自 firebase 的响应是一个对象数组,那么您需要使用 map 函数在 UI 中呈现所有对象。

    【讨论】:

    • 感谢您的回复,@Sri!我最终使用上面的代码,利用setState() 并通过useEffect 执行它。我认为我遇到的一个问题是我的播放器对象中的一个子名称(player_data)与我将数据存储在(player_data)中的变量名称冲突。欢迎来到 SO,顺便说一句。 :]
    • 很好听 :),全局变量和对象属性不会发生冲突,由于块作用域,它将被视为单独的。
    【解决方案2】:

    当您从 Firebase 获取播放器数据时,您需要将播放器数据存储在组件的状态中(通过调用 setStateuseState 挂钩),以便触发重新渲染。然后,您的渲染代码可以从状态中读取数据。

    在此处查看我的答案的一个非常简短的示例:Initiate React components with data from Firebase database? 或略长一点的示例:Retrieving items from firebase and dynamiccaly populating it in react native

    【讨论】:

    • 您好弗兰克,感谢您的回复!我试图将带有 useState 的 player_data 存储为 const JSON 变量,如下所示,结果收到“TypeError:无法读取未定义的属性(读取'settlement_name')”,如上面的编辑所示。知道如何进行吗?
    • 是的,现在这是一个完全不同的问题。不确定我们是否仍然可以合理地称这个问题为同一个问题,但乍一看你的初始状态(你传递给useState(),没有player_data 属性。我认为你可能不应该传递一个数组在那里,因为在您的数据库中您也没有数组。
    • 再次感谢您的回复,弗兰克!我已编辑问题以更准确地反映我的目标。为我的新手道歉,但我应该如何设置我的 useState() 挂钩来捕获 player_data 对象?我以为我正在将player_data 属性与[playerdata, setPlayerData] 中的第一个变量一起应用?我也删除了数组大括号,谢谢。 :)
    • 由于您在渲染代码中检查{player_data &amp;&amp; ,因此您可以不定义初始状态。所以const [ player_data, setPlayerData ] = useState();除此之外,如果没有更多的调试信息,很难说发生了什么。例如:发生了什么日志记录?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多