首页 > 解决方案 > 为什么它首先呈现“未定义”然后在日志中显示对象

问题描述

即使代码在应用程序中只有一个 console.log,我应该如何修复我的 React 应用程序,它呈现两个具有不同结果的日志?是的,我在 index.js 文件中删除了 <React.StrictMode>,因为它还会触发两次渲染。在终端中,第一个日志是未定义的,第二个是带有数据的对象,因为当我使用数组映射方法时,它一直说“ BookDetail.jsx:26 Uncaught TypeError: bookData.map is not a function ”。

我正在尝试从 firebase 数据库中获取有关一本书的详细信息。我的目标很简单,前端用户点击书名,进入详细页面。所有数据都存储在 Firestore 数据库中。详细页面代码如下,希望有人能帮帮我,谢谢!

import React, {useState, useEffect} from 'react'
import {Link} from 'react-router-dom'
import firebase from '../config/fbConfig'

const BookDetails = (props) => {
    const id = props.match.params.id
    const db = firebase.firestore()
    const [books, setBooks] = useState('')
        useEffect(() => {
            db.collection("books")
            .doc(id)
            .get()
            .then(doc => doc.data())
            .then(data => setBooks(data))
            },[])
            const bookData = {books}             

    return (
        <div className="book_details">
            <Link to="/"><h2>Home</h2></Link>     
                {console.log(bookData)}
            <h1>The Summary Of the Book </h1>
                {bookData.map(book => <div key={book.id}> {book.brief} </div>)}
        </div>
    )
}
export default BookDetails

标签: reactjsfirebaseconsole.log

解决方案


根据 ReactJS 文档,建议在组件的顶层调用钩子:https ://reactjs.org/docs/hooks-rules.html

所以看起来当你的组件挂载它调用你的自定义 useBooks 钩子。

它初始化书籍状态,然后执行 useEffect。但是,我认为调用 Firestore db 函数是一个异步过程,因为您没有等待响应,所以您的函数返回未定义。

看来您可能不需要自定义挂钩。在顶层设置 useState 和 useEffect。

const BookDetails = (props) => {
    const id = props.match.params.id
    const db = firebase.firestore()
    const [books, setBooks] = useState([])

           useEffect(() => {
             const fetchBooks = () => {
                db.collection("books")
                  .doc(id)
                  .get()
                  .then(doc => doc.data())
                  .then(data => setBooks(data))
               }
             fetchBooks()
            },[])

    return (
        <div className="book_details">
            <Link to="/"><h2>Home</h2></Link>     
                {console.log(books.title)}
            <h1>The Summary Of the Book </h1>
                {books && books.map(book => <div key={book.id}> {book.brief} </div>)}
        </div>
    )
}
export default BookDetails

const data = doc.data() 似乎是一个异步函数,因此您可能希望为 setBooks 链接另一个 .then


推荐阅读