使用动态名称中的React元素(字符串)

时间:2018-02-28 16:00:34

标签: reactjs

我试图动态更改元素名称以重用函数。

  static renderDetails(props, parentTableElementOpen, parentTableElementClose, ) {
let coverageRows;
if (props.length !== 0) {
  return (
    <span>
      {parentTableElementOpen}
      {props.map((columnData, index) => {
        if (index === props.length - 1) {
          coverageRows = (<TableRowCol classNames={styles.text_align_right}>{columnData}</TableRowCol>);
        }
        else {
          coverageRows = (<TableRowCol>{columnData}</TableRowCol>);
        }
        return coverageRows;
      })}
      {parentTableElementClose}
    </span>
  );
}
return null;

}

此功能的调用如下。

Utils.renderDetails(this.props.columnData, '<TableRow>', '</TableRow>');

parentTableElementOpenparentTableElementClose将包含我之后的元素的名称。

呈现的页面似乎无法识别它们而不是<TableRow> </TableRow> element type它只呈现文本<TableRow> </TableRow>

我在这里尝试做的事情可能有点棘手或过于复杂,但认为它可能是两个相同功能之间的一个很好的重构。

1 个答案:

答案 0 :(得分:1)

可能有一个解决方案实际上可以按照您描述的方式工作,但我认为您正在使用HTML思维方式来思考这个问题。请注意,使用React,即使它与语法有相似之处,您也会呈现不是HTML标记/ XML的Component

在你的情况下,你传递一个字符串,以便它呈现一个字符串。

我认为你想要的是一个渲染孩子的通用组件,而不是一个试图挑选组件的函数。也许是这样的:

class MyTableRow extends React.Component {
  render() {
    return ( //do whatever customization you want here.
        <TableRowCol>
          {this.props.children} //renders what's "inside" the tag. You can pass this or specify it in the JSX
        </TableRowCol>
    )
  }
}

如果您考虑在该实用程序调用中正在执行的操作,您实际上指定了要使用的标记,然后只传递在React世界中的道具与:

//Some render function
...
<MyUtilityObject props={props} />
...

我的第一直觉是&#34;反转&#34;使用组件的设计似乎就是React的设计方式。

修改 我没有意识到element.props.children是readonly所以下面的想法是不会起作用。

我在这种情况下的建议如上。一般来说,这个抽象方法实际上并没有做任何事情,可以重构为自定义组件,所以不使用函数调用而是使用组件

<MyTable>
  { row.map( (row, index) => {
    switch(row.type) {
      case 'data1':
        return <MyCustomRow row={row} key={index} />
      case 'data2':
        return <MyCustomRow2 row={row} key={index} />
      default: 
       return null
    }
  })
</MyTable>

<强> NOPE 既然如此,如果你想保持这个签名并且你有充分的理由你可能想要做的是:

static renderDetails(props, parentElement) {
    if(props.length === 0) {
        return null; //nothing to see here!
    }
let coverageRows;

let children = props.map((columnData, index) => {
        if (index === props.length - 1) {
          coverageRows = (<TableRowCol classNames={styles.text_align_right}>{columnData}</TableRowCol>);
        }
        else {
          coverageRows = (<TableRowCol>{columnData}</TableRowCol>);
        }
        return coverageRows;
})

parentElement.children = children
return <span>parentElment</span> //I'm not sure why you need the span, but if you do great. I would just return the parentElement
}

//Called by...
render() {
    ...
    renderDetails(props, <TableRow />)//an actual table row instance, not the tag name as a string
    ...
}

我没有测试任何这个,但它应该让你朝着正确的方向前进。我建议编写一个自定义组件,让孩子们了解它是如何工作的。它将为您节省大量时间。