代码之家  ›  专栏  ›  技术社区  ›  Jacksonkr

动态地向jsx/组件添加子组件

  •  0
  • Jacksonkr  · 技术社区  · 7 年前

    形势

    我试图呈现一个基于模板jsx片段的组件。原因是我的应用程序中有一些这样的情况,但是有一些细微的定制,我宁愿把定制的业务逻辑留给相应的组件,而不是工厂。

    例子

    父模板

    <div></div>
    

    子模板

    <p></p>
    

    在render函数中,我想将n个子组件添加到父组件。所以如果n=4,我希望输出如下

    <div>
        <p></p>
        <p></p>
        <p></p>
        <p></p>
    </div>
    

    我试着用 parentTemplate.children.push 但没有效果,因为此时组模板仍然是JSX,还不是呈现的组件。如何使用jsx+react完成此任务?

    额外的

    到目前为止,我的实际代码是这样的

    render() {
    
        let groupTemplate = <ListGroup></ListGroup>
    
        let itemTemplate = (item) => {
            return <ListGroup.Item>{item.name}</ListGroup.Item>;
        }
        if (this.props.itemTemplate) itemTemplate = this.props.itemTemplate;
    
        let itemsJsx;
        this.props.navArray.forEach((item) => {
            groupTemplate.children.push(itemTemplate(item))
        });
    
        return (
            [groupTemplate]  
        );
    }
    

    从父对象:

    const groupTemplate = <ListGroup className='custom-container-classes'></ListGroup>
    const itemTemplate = <ListGroup.Item className='customized-classes'></ListGroup.Item>
    <NavigationFactory groupTemplate={groupTemplate} itemTemplate={itemTemplate}>
    </NavigationFactory>
    
    0 回复  |  直到 7 年前
        1
  •  1
  •   Jacksonkr    7 年前

    不清楚你的问题,但我试图根据你的代码找出你想做什么,看看是否有用,否则我会删除我的答案。

    下面代码工作的机制是它接受groupTemplate,在您的例子中,您将把它作为一个道具传入,然后在其中接受子级并返回组合在一起的子级。如果没有传递相关的道具,并且渲染器中有一个mapper函数,可以使用默认的子组模板来确定要使用和渲染的模板 n 次数基于 navArray 长度。

    componentDidMount() {
        // setup default templates
    
        if (!this.props.navButtonContainerTemplate) {
            this.prop.navButtonContainerTemplate = (items) => {
                return <ListGroup>{items}</ListGroup>
            }
        }
    
        if (!this.props.navButtonTemplate) {
            this.props.navButtonTemplate = (item) => {
                return (
                    <ListGroup.Item>
                        {item.name}
                    </ListGroup.Item>
                )
            }
        }
    }
    
    render() {
    
        const itemsJsx = this.props.navArray.map(obj => {
            const itemJsx = this.props.navButtonTemplate(obj)
            return itemJsx;
        });
    
        return this.props.navButtonContainerTemplate(itemsJsx);
    }
    
        2
  •  2
  •   Domino987    7 年前

    您可以使用渲染道具,这是实现类似效果的最佳方法:

    家长:

    <NavigationFactory 
         itemTemplate={itemTemplate}
         render={children => <ListGroup className='custom-container-classes'>
              {children}
         </ListGroup>}
     />
    

    孩子:

    render() {
         this.props.render(this.props.navArray.map(item => <ListGroup.Item key={item.id}>
           {item.name}
      </ListGroup.Item>))
    }
    

    这将允许您在调用函数上定义容器,并允许您根据需要创建chidlren。

    希望这有帮助。

        3
  •  0
  •   Ross Allen    7 年前

    将内容作为常规子级传递给 ListGroup 通过标准JSX嵌套:

    render() {
        let itemTemplate = (item) => {
            return <ListGroup.Item>{item.name}</ListGroup.Item>;
        }
        if (this.props.itemTemplate) itemTemplate = this.props.itemTemplate;
    
        return (
            <ListGroup>
                {this.props.navArray.map(item => (
                    itemTemplate(item)
                ))}
            </ListGroup>
        );
    }