我是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
答案 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
。