0

我已经看到包和库能够console.log使用 HOCs + 基本组件。由于以下原因,我对如何实现它感到非常困惑:

  • 类组件的名称定义为component.displayName
  • 功能组件有component.name
  • HOC 没有获取嵌套 HOC 和组件名称的标准方法

例如一个样本 HOC

function NamePrinter(Wrapped) {
  return (class Wrapper extends React.Component {
    componentWillReceiveProps() {
      console.log(`the name of this component is ${Wrapped.displayName || Wrapped.name}`)
    }
    render() {
      return <Wrapped {...this.props} />
    }
  })
}

据我所知,这真的是如何得到的。例如,在获取名称react-redux方面有自己的约定,但这意味着我在搜索名称时只能“深入一层”。

如果我有一个这样包装的组件:

NamePrinter(connect(() => ({}), null)(withStyles({})(React.memo(MyComponent))))

如何console.log使用我的示例 HOC

connect(withStyles(React.memo(MyComponent)))

或具有相同表现力的类似事物?

4

1 回答 1

0

我能得到的最接近的算法。如前所述,没有标准的方法来公开包装的组件。因为material-ui, 它被称为Naked, 而react-reduxis WrappedComponent。未优化算法

// assuming material-ui and react-redux only
function getDisplayName(component) {
    function getName(type) {
        let str = "";
        if (type.displayName) {
            str += "(" + type.displayName;
        } else if (type.name) {
            str += "(" + type.name;
        }

        if (type.Naked && getName(type.Naked)) {
            str += getName(type.Naked);
        } else if (type.WrappedComponent && getName(type.WrappedComponent)) {
            str += getName(type.WrappedComponent);
        } else if (type.render && getName(type.render)) {
            str += getName(type.render);
        } else if (typeof type === "string") {
            str += type;
        } else if (type.type && getName(type.type)) {
            str += getName(type.type);
        }
        return str;
    }

    let currStr = getName(component);
    const openParenCount = Array.from(currStr).filter(el => el === "(").length;
    const closeParenCount = Array.from(currStr).filter(el => el === ")").length;
    return (
        currStr + [...Array(openParenCount - closeParenCount)].map(el => ")").join("")
    )
}
于 2019-08-31T03:02:34.720 回答