Gatsby在运行时替换静态查询数据

时间:2020-07-12 20:54:19

标签: reactjs gatsby

我是Gatsby&React的新手,我试图找出如何充分利用预渲染和动态数据的双重优势。

对于在构建时获取数据并将其作为道具传递给呈现每个菜单项的Menu组件而言,单独使用查询非常有用。但是,在运行时,我想再次从数据库中提取数据,并让它更新数据,例如,是否存在价格变动等。

我知道我可以重新构建整个项目,但我希望将此作为后备。

当数据库调用完成时,如何使查询将数据发送到Menu组件,然后[再次发送数据?]。

当前无法正常工作的代码:

index.jsx

import React, { useEffect } from "react"

import Layout from "../components/layout"
import SEO from "../components/seo"

import Menu from '../components/menu'
import { graphql } from "gatsby"

import firebase from "gatsby-plugin-firebase"
const IndexPage = (props) => {



  useEffect(() => {
    // use this hook to make db call and re-render menu component with most up to date data

    var db = firebase.firestore();
    let docs = []
    db.collection(`public/menu/${process.env.restaurantId}`).get().then(val => {

      val.forEach(doc => {
        docs.push({ node: doc.data() })
      });
      console.log('docs', docs)
      props.data.allMenuItem.edges = docs;  // i have no idea what i'm doing
    })


  }, [])


  return (
    <Layout>
      <SEO title="Home" />
      <Menu menuItems={props.data.allMenuItem.edges}></Menu>
    </Layout>
  )
}

// use this query for prerendering menu items
export const query = graphql`
query MyQuery   {
  allMenuItem {
    edges {
      node {
        available
        name
        group
      }
    }
  }
}
`;

export default IndexPage

1 个答案:

答案 0 :(得分:1)

您不应修改React属性;任何可以更改的值都应该是组件状态的一部分。参见Can I update a component's props in React.js?

但是,以下代码应该做到这一点。创建一个状态并将其属性值设置为默认值。然后在客户端上加载数据后对其进行更新。

const IndexPage = props => {
  const [menuItems, setMenuItems] = useState(props.data.allMenuItem.edges.map(({node}) => node))

  useEffect(() => {
    // use this hook to make db call and re-render menu component with most up to date data
    let db = firebase.firestore()

    db.collection(`public/menu/${process.env.restaurantId}`)
      .get()
      .then(setMenuItems)
  }, [])

  return (
    <Layout>
      <SEO title="Home" />
      <Menu menuItems={menuItems}></Menu>
    </Layout>
  )
}

请注意,我已切换为使用从Firestore(没有node)获得的数据格式,而不是从Gatsby获得的数据格式,因此您需要修改Menu组件以免出现意外情况如果您使用此代码,则可以额外嵌套一层(使用node