样式化组件React HTML元素工厂

时间:2020-08-15 16:16:25

标签: javascript reactjs typescript styled-components

我想创建一个处理具有相同属性/逻辑的多个HTML元素的组件。

  $alldata = array();
  $colno = 0;
  $rowcount = 0;
  // Execute multi query
if (mysqli_multi_query($conn, $sql)) {
  do {
    if ($result = mysqli_store_result($conn)) {
      $rowno = 0;
      while ($row = mysqli_fetch_row($result)) {
        foreach ($row as $value) {
          $alldata[$rowno][$colno] = $value;
          $rowno++;
        }
        //count rows in current pass; keep highest value
        if ($rowno > $rowcount) {
          $rowcount = $rowno;
        }
      }
      $colno++;
      mysqli_free_result($result);
    }
  } while (mysqli_next_result($conn));
}
//dump array into table
$outputtable .= "<table>";
for ($i = 0; $i <= $rowcount-1; $i++) {
  $outputtable .= "<tr>";
  for ($j = 0; $j <= $colcount; $j++) {
    if (isset($alldata[$i][$j])) {
      $outputtable .= "<td>" . $alldata[$i][$j] . "</td>";
    }
    $outputtable .= "</tr>";
  }
}    
$outputtable .= "</table>";
echo $outputtable;

它失败并显示该错误:

import React from 'react';
import styled from 'styled-components';

interface GridProps {
  htmlElement: 'div' | 'main' | 'header',
}

const GridFactory = (props: GridProps) => {
  switch (props.htmlElement) {
    case 'header':
      return styled.header``;
    case 'main':
      return styled.main``;
    case 'div': default :
      return styled.div``;
  }
}

export const Test = () => (
  <GridFactory htmlElement='div'>
    <p>content...</p>
  </GridFactory>
)

尝试过的第一把戏

为GridProps添加一个显式的子道具:

Type '{ children: Element; htmlElement: "div"; }' is not assignable to type 'IntrinsicAttributes & GridProps'.
  Property 'children' does not exist on type 'IntrinsicAttributes & GridProps'.

它给出了相应的错误:

interface GridProps {
  htmlElement: 'div' | 'main' | 'header',
  children?: React.ReactNode | React.ReactNode[];
}

我该如何实现?

2 个答案:

答案 0 :(得分:2)

由于您的styled.head返回的是组件类型,而不是React.Element,因此您可以按以下方式改进内容:

将组件的返回类型指定为无状态功能组件React.SFC,由于它是children类型的一部分,因此无需指定SFC属性就可以从中受益: >

const GridFactory: React.SFC<GridProps> = (props) => { ...

然后将样式化的组件分配为功能组件,例如Header

const Header: React.SFC = styled.header``;

总而言之,完整代码为:

interface GridProps {
  htmlElement: 'div' | 'main' | 'header',
}

const Header: React.SFC = styled.header``;

const GridFactory: React.SFC<GridProps> = (props) => {
  switch (props.htmlElement) {
    case 'header':
      return <Header />;

    // More to come

    default: return null
  }
}

答案 1 :(得分:1)

该错误表明您无法将prop“子级”传递给组件,因为它没有在prop接口声明中提供该类型。实际上,您的GridProps接口没有声明此类属性。 children是您在将子组件传递给父组件时“设置”的道具,例如您的示例

export const Test = () => (
  <GridFactory htmlElement='div'>
    <p>content...</p> //This is passed as the children prop of your GridFactory
  </GridFactory>
)

要使打字稿停止抱怨,您应该将接口声明更改为

interface GridProps {
  htmlElement: 'div' | 'main' | 'header';
  children: React.Node | React.Node[];
}

现在您的道具类型允许您传递儿童道具