- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 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/
我是一名优秀的程序员,十分优秀!