gpt4 book ai didi

javascript - 如何从 JSON 文件在 Gatsby 中创建页面?

转载 作者:行者123 更新时间:2023-11-28 03:41:37 25 4
gpt4 key购买 nike

我正在尝试使用 JSON 文件在 Gatsby 中动态创建页面。在该文件中,我定义了应该在页面中呈现的组件。

我遵循了 Gatsby 的文档,但是它没有我想要的。因此,我尝试通过读取 JSON 文件并遍历其中的组件并使用 React.createElement() 创建它们来创建页面。最后,我得到了一个 React 组件数组,我将其传递给模板页面组件的 createPage 方法的上下文对象中的 Children 属性。

这是解决这个想法的正确方法吗?这在 Gatsby 中可行吗?

我认为说我尝试过动态导入并且效果很好是有用的,但我正在尝试找到一种不必将所有组件转储到一个文件夹中的方法。

我有这个项目的 Github 存储库。 https://github.com/ahmedalbeiruti/Gatsby-dynamic-pages

这是代码的主要部分:

gatsby-node.js

exports.createPages = ({actions})=>{
const {createPage} = actions
const resutl = componentsRenderer(data.page.layout.columns)
createPage({
path: data.page.name,
component: path.resolve('./src/template/page.js'),
context:{
children: resutl
}
})
}

const componentsRenderer = components => {

return components.map(component => {
let children = []
if (component.children){
children = componentsRenderer(component.children)
}
const element = require(`${__dirname}/${component.path}`)

return React.createElement(element, Object.assign({},{key: component.key},{...component.props}),children)
});
}

数据/sample-page-no-props.json

{
"page":{
"name": "about",
"layout":{
"columns": [
{
"key":"column_1",
"name": "Column",
"path": "/src/components/layouts/column.jsx",
"children":[
{
"name": "FirstComponent",
"path": "/src/components/custom/first-component.jsx",
"key": "first_component_1"
}
]
},
{
"key": "column_2",
"name": "Column",
"path": "/src/components/layouts/column.jsx",
"children":[
{
"key": "second_component_1",
"name": "SecondComponent",
"path": "/src/components/custom/second-component.jsx",
"children":[
{
"key": "leaf_component_1",
"name": "LeafComponent",
"path":"/src/components/custom/leaf-component.jsx"
}
]
},
{
"key": "third_component_1",
"name": "ThirdComponent",
"path": "/src/components/custom/third-component.jsx",
"children":[
{
"key": "leaf_component_1",
"name": "LeafComponent",
"path":"/src/components/custom/leaf-component.jsx"
}
]
}
]
}
]
}
}
}

data/sample-page-with-style-prop.json(FirstComponent 有 props 对象)

{
"page":{
"name": "about",
"layout":{
"columns": [
{
"key":"column_1",
"name": "Column",
"path": "/src/components/layouts/column.jsx",
"children":[
{
"name": "FirstComponent",
"path": "/src/components/custom/first-component.jsx",
"key": "first_component_1",
"props":{
"style":{
"color":"red"
}
}
}
]
},
{
"key": "column_2",
"name": "Column",
"path": "/src/components/layouts/column.jsx",
"children":[
{
"key": "second_component_1",
"name": "SecondComponent",
"path": "/src/components/custom/second-component.jsx",
"children":[
{
"key": "leaf_component_1",
"name": "LeafComponent",
"path":"/src/components/custom/leaf-component.jsx"
}
]
},
{
"key": "third_component_1",
"name": "ThirdComponent",
"path": "/src/components/custom/third-component.jsx",
"children":[
{
"key": "leaf_component_1",
"name": "LeafComponent",
"path":"/src/components/custom/leaf-component.jsx"
}
]
}
]
}
]
}
}
}

模板/page.js

import React from 'react'
import Layout from '../components/layouts/Layout'

const Page = (props)=>{
console.log(`page_context: ${props.pageContext.children}`)
return (
<>
<h1>this is the about page</h1>
<Layout>
{props.pageContext.children}
</Layout>
</>
)
}

export default Page

组件/自定义/first-component.jsx

// import React from "react";

const React = require("react");

module.exports = (props)=>{
return(
<h3 style={props.style}>
Hi this is the first component
</h3>
)
}

// export default FirstComponent

使用sample-page-with-style-prop.json 文件时遇到的错误如下:

UNHANDLED REJECTION Cannot assign to read only property 'style' of object '#<Object>'

TypeError: Cannot assign to read only property 'style' of object '#<Object>'

如果我更改为sample-page-no-props.json 文件,我会收到以下错误:

UNHANDLED REJECTION Cannot assign to read only property 'children' of object '#<Object>'

TypeError: Cannot assign to read only property 'children' of object '#<Object>'

最佳答案

而不是将组件作为上下文传递给页面模板。正确的方法是传递数据并在页面内渲染组件

gatsby-node.js

exports.createPages = ({actions})=>{
const {createPage} = actions
const resutl = componentsRenderer(data.page.layout.columns)
createPage({
path: data.page.name,
component: path.resolve('./src/template/page.js'),
context:{
children: resutl
}
})
}

template/page.js

import React from 'react'
import Layout from '../components/layouts/Layout'

const componentsRenderer = components => {

return components.map(component => {
let children = []
if (component.children){
children = componentsRenderer(component.children)
}
const element = require(`${HOME_DIR}/${component.path}`)

return React.createElement(element, Object.assign({},{key: component.key},{...component.props}),children)
});
}
const Page = (props)=>{
const data = props.pageContext.children
return (
<>
<h1>this is the about page</h1>
<Layout>
{componentsRenderer(data)}
</Layout>
</>
)
}

export default Page

PS:确保页面组件中的HOME_DIR路径正确。

关于javascript - 如何从 JSON 文件在 Gatsby 中创建页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57264220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com