【问题标题】:How can I write generic react component wrappers如何编写通用反应组件包装器
【发布时间】:2020-08-25 01:40:31
【问题描述】:

我有一组使用一组通用属性的功能组件,例如:

const A = ({ x, y, z }) = {...}
const B = ({ x, y, z }) = {...}

我对这些组件有部分固定的配置:

const styles {
    A: {
        type1: {
            x: 1,
            y: "something",
        },
    },
    B: {
        type1: {
            x: 2,
            y: "else",
        },
    },
};

为了使用这些配置,我一直在为每个配置编写一个固定组件:

// i have SFCs for A1, A2, B1, B2, C1, C2, ... etc.
const A1 = (props) = {
    return <A x={styles.A.type1.x} y={styles.A.type1.y} {...props} />
}

...

// inside my business logic component
return (
    <A1 z="state" />
)

这对于少量组件和部分道具组来说是可以的。但是,今后我希望能够做这样的事情:

type A1 = styledType(styles.A.type1)(A);
return <A1 z="some_state" />

我需要在类型脚本文件中定义styledType 吗?在默认的 create-react-app 代码库中混合 TS 和 JSX 可以吗?

我可以在 JSX 中引用类型(没有实例)吗?我上面写的有效吗?

如果有什么东西已经这样做了(反应,甚至只是普通的 JS / JSX / TS / 什么),我全都听好了!

到目前为止,这是我一直在玩的:

const styledTyped = (styles) => {
    return (component: C) => <C {...styles} />; // ????
};

export default styledTyped;

我知道我需要返回一个采用组件类型的可调用对象,并返回一个将注入这些属性的类型包装器。

虽然我不知道该怎么做...我目前正在学习材料 UI 的 withStyles,但它有很多事情要做,而且对于没有这些语言经验的人来说有点难以理解。


编辑:

在查看了withStyles@material-ui/styles/withStyles/withStyles.js 中的实现之后,我已经更接近了。我有这样的事情:

const withElementStyles = (styleProps) => {
  return (Component) => {
    return (props) => {
      const newElement = React.createElement(Component, { ...props, ...styleProps });
      return newElement;
    };
  };
};

这几乎可以工作了。它确实创建了具有固定属性的组件,以及我传递给包装器的那些。但是,我似乎丢失了 instance.type.name 属性,这是我用来执行基于类型的几个函数调用的调度的。

【问题讨论】:

    标签: reactjs typescript jsx


    【解决方案1】:

    我找到了一个解决方案(在了解了 defaultProps 之后),但也不得不调整其他代码(为了更好)。

    我现在有了这个:

    const withStyledElement = (fixedProps) => {
      return (Component) => {
        const StyledElement = (props) => {
          return <Component {...props} />;
        };
        StyledElement.defaultProps = fixedProps;
        StyledElement.displayName = Component.name;
        StyledElement.getConnector = Component.getConnector; // see below
        return StyledElement;
      };
    };
    

    我在上面提到过我使用组件名称来执行类型分派。当我使用像这样的包装组件时,这失败了:

    const WrappedA = withElementStyles(styles.A.1)(A);
    

    因为组件名称是“StyledElement”。

    我认为依赖名称不是一个好方法。当时我没有意识到你可以在定义函数后将它们绑定到组件。

    因此,我没有使用名称进行调度,而是使用了预期的绑定方法:

    const getConnector = (instance, arg) => {
        return instance.getConnector(instance, arg);
    }
    

    现在我不必为每种类型添加案例,我可以创建单线包装的组件来满足我需要的所有口味。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2020-03-11
      相关资源
      最近更新 更多