Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何从JSON文件在Gatsby中创建页面?_Javascript_Reactjs_Gatsby_React Context - Fatal编程技术网

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

Javascript 如何从JSON文件在Gatsby中创建页面?,javascript,reactjs,gatsby,react-context,Javascript,Reactjs,Gatsby,React Context,我正在尝试使用JSON文件在Gatsby中动态创建一个页面。在该文件中,我定义了应该在页面中呈现的组件 我遵循盖茨比的文档,但是,它没有我想要的。因此,我试图通过读取JSON文件并遍历其中的组件并使用React.createElement()创建页面。最后,我得到了一个react组件数组,我将该数组传递给createPage方法上下文对象中的一个children prop,并将其传递给模板页面组件 这是解决这个问题的正确方法吗?这在盖茨比是否可行 我想说我尝试了动态导入,效果很好,这是很有用的,

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

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

这是解决这个问题的正确方法吗?这在盖茨比是否可行

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

我有这个项目的Github回购协议。

以下是代码的主要部分:

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)
    });
}

data/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.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
从“React”导入React
从“../components/layouts/Layout”导入布局
常量页面=(道具)=>{
log(`page\u context:${props.pageContext.children}`)
返回(
这是关于页面
{props.pageContext.children}
)
}
导出默认页面
components/custom/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
//从“React”导入React;
常量反应=要求(“反应”);
module.exports=(道具)=>{
返回(
嗨,这是第一个组件
)
}
//导出默认组件
我在使用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>'
无法将未处理的拒绝分配给对象“#”的只读属性“style”
TypeError:无法指定对象“#”的只读属性“style”
如果更改为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>'
无法将未处理的拒绝分配给对象“#”的只读属性“children”
TypeError:无法分配给对象“#”的只读属性“children”

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

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
        }
    })
}
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
模板/page.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
        }
    })
}
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
从“React”导入React
从“../components/layouts/Layout”导入布局
const componentsrender=组件=>{
返回components.map(component=>{
让孩子们=[]
if(子组件){
children=componentsrender(component.children)
}
const element=require(`${HOME\u DIR}/${component.path}`)
返回React.createElement(元素,对象.assign({},{key:component.key},{…component.props}),子元素)
});
}
常量页面=(道具)=>{
const data=props.pageContext.children
返回(
这是关于页面
{componentsrender(数据)}
)
}
导出默认页面

PS:确保页面组件中的
HOME\u DIR
路径正确。

非常感谢您的回复,我正在尝试您的建议。不幸的是,它没有起作用。我得到错误:元素类型无效:需要字符串(对于内置组件)或类/函数(对于复合组件),但得到:对象。这可能是因为我没有将require更改为es6导入(实际上使用可加载组件),但这将使它成为一个动态导入,我已经这样做了,而且效果很好。我正在寻找替代方案,因为我的团队选择不进行动态导入。似乎您应该将组件作为默认值导出,并作为默认值导入,如
const element=require(`${HOME\u DIR}/${component.path}`)。默认值