【问题标题】:Styled-components React HTML elements factoryStyled-components React HTML 元素工厂
【发布时间】:2020-12-05 06:05:55
【问题描述】:

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

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

它因该错误而失败:

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

尝试了第一个技巧

向 GridProps 添加显式的 children 道具:

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

它给出了相应的错误:

'GridFactory' cannot be used as a JSX component.
  Its return type 'StyledComponent<"header", DefaultTheme, {}, never> | StyledComponent<"div", DefaultTheme, {}, never>' is not a valid JSX element.
    Type 'StyledComponent<"header", DefaultTheme, {}, never>' is not assignable to type 'Element | null'.
      Type 'String & StyledComponentBase<"header", DefaultTheme, {}, never> & NonReactStatics<never, {}>' is missing the following properties from type 'Element': type, props, key

我怎样才能实现它?

【问题讨论】:

    标签: javascript reactjs typescript styled-components


    【解决方案1】:

    该错误表明您无法将道具“孩子”传递给您的组件,因为它没有在道具接口声明中提供该类型。事实上,您的 GridProps 接口并没有声明这样的属性。 children 是您在将子组件传递给父组件时“设置”的道具,就像在您的示例中一样

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

    要让 typescript 不再抱怨它,你应该将你的接口声明更改为

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

    现在你的 Prop 类型允许你传递一个 children 道具

    【讨论】:

    • 我已经尝试过了,但没有成功,我将编辑我的问题以添加它和相应的错误输出。
    【解决方案2】:

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

    将您的组件的返回类型指定为无状态功能组件React.SFC,您也可以从中受益,无需指定children prop,因为它是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
      }
    }
    

    【讨论】:

    • 这个答案我也学到了很多,非常感谢
    猜你喜欢
    • 2019-12-21
    • 2019-12-21
    • 2017-07-20
    • 2018-04-14
    • 2020-02-15
    • 2017-06-17
    • 2021-08-26
    • 2018-03-06
    • 2020-01-08
    相关资源
    最近更新 更多