【问题标题】:Rendering React components from json data dynamically从 json 数据动态渲染 React 组件
【发布时间】:2018-07-02 08:06:04
【问题描述】:

我有一个像这样的 json 对象:

let data = {
            UI: {
                "baseType":"App",
                "children":[
                    {
                        "baseType":"TextField",
                        "props":{

                        }
                    }
                ]
            }
        };

我想把它渲染成这样:

<App>
 <TextField>
 </TextField>

所以,我需要从 json 对象中获取动态渲染的组件。同样,我写了一个方法:

getFromJson(obj) {
    // let Type = obj.baseType;

    let children = obj.children
        ? obj.children.map((obj) => {
                return this.getFromJson(obj,obj.baseType);
            })
        : '';
    // <></
    switch (obj.baseType) {
        case "App":

            return (
                <App key={key} {...obj.props}>
                    {children}
                </App>
            );
        case "TextField":
            //      {children}
            //  </TextField>);
            return (<TextField key={key} {...obj.props}>
                    {children}
                </TextField>
            );
        default:
            return <h1>Returning default case.</h1>;
    }

    // return <div>Hello</div>
}

我在调用上面的方法:

render() {

        let renderedUI = "";
        if (this.props.json.UI) {
            renderedUI = this.getFromJson(this.props.json.UI, "UI");
        }

        return renderedUI;
    }

输出只是 App 组件,即没有渲染子级。孩子们虽然有价值:{$$typeof: Symbol(react.element), key: "TextField", ref: null, props: {…}, type: ƒ, …}

我做错了什么?

编辑:我的整个组件是:

import React from "react";
import TextField from "./TextField";
import App from "./App";

export default class RenderFromJson extends React.Component {
    constructor() {
        super();
        this.getFromJson = this.getFromJson.bind(this);
    }

    componentWillMount() {}

    getFromJson(obj,key) {
        // let Type = obj.baseType;

        let children = obj.children
            ? obj.children.map((obj) => {
                    return this.getFromJson(obj,obj.baseType);
                })
            : '';
        // <></
        switch (obj.baseType) {
            case "App":

                return (
                    <App key={key} {...obj.props}>
                        {children}
                    </App>
                );
            case "TextField":
                //      {children}
                //  </TextField>);
                return (<TextField key={key} {...obj.props}>
                        {children}
                    </TextField>
                );
            default:
                return <h1>Returning default case.</h1>;
        }

        // return <div>Hello</div>
    }

    render() {

        let renderedUI = "";
        if (this.props.json.UI) {
            renderedUI = this.getFromJson(this.props.json.UI, "UI");
        }

        return renderedUI;
    }
}

文本字段:

import React from "react";

export default class TextField extends React.Component {
    constructor() {
        super();
    }


    render() {
        console.log("returning from textfield");
        return <h1>Hi from textfield</h1>;
    }
}

App.js

import React from "react";
import axios from "axios";

import RenderFromJson from "./RenderFromJson";

export default class App extends React.Component {
    constructor() {
        super();
    }

    componentWillMount() {}

    render() {

        return <h2>In App</h2>;
    }
}

【问题讨论】:

  • 谢谢。但是,那是一个巨大的图书馆。我正在寻找与我的场景相关的答案。
  • 没那么大。考虑努力通过大量示例学习经过良好测试的实现,而不是尝试重新发明轮子。
  • 你能发TextField组件吗?
  • @Ali 请看一下。

标签: javascript reactjs


【解决方案1】:

最后一小时后我发现了问题,您的App 组件将在props 对象中获得children 数组,您必须将子组件附加到您的App 组件中

export default class App extends React.Component {
    constructor() {
        super();
    }

    render() {
        return <div>
            <h1>In App</h1>
            {this.props.children /* this what solve the issue */} 
        </div>
    }
}

【讨论】:

    【解决方案2】:
    GetFromJson = ({ children }) => {
       return children.map(elem => {
           const Tag = elem.baseType
           const props = { elem }
           return (
              <Tag> ...props </Tag>
           )
       })
    }
    

    然后在你的组件中

    render(){
       return <GetFromJson children={this.props.json.UI.children} />
    }
    

    我只是想知道,你有什么道具?因为也许我们需要改变 ...props

    【讨论】:

    • 我也可以有嵌套的孩子。您的案例仅在儿童级别处理。
    • 只要创建一个条件,如果您有嵌套的孩子,将返回另一个数据映射,例如,您检查道具中是否有关键孩子,如果您这样做而不是 return ...props in你 你返回一张 props.children 的地图
    • 我认为这是我在原始代码中所做的。
    • 你只像我一样对第一个孩子做一个循环,现在是为了测试目的而不是返回 ...props ,做 !props.children 吗? ...道具:空
    【解决方案3】:

    可能你的绑定有问题,试试这个

    constructor(props) {
      super(props);
    
      this.getFromJson = this.getFromJson.bind(this);
    }
    

    【讨论】:

    • 不,同样的结果。
    猜你喜欢
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 2022-11-11
    相关资源
    最近更新 更多