【问题标题】:How to identify component name from a object array如何从对象数组中识别组件名称
【发布时间】:2019-04-15 15:26:14
【问题描述】:

目前我有以下

methodName = () => {
  const {
    collectionOfComponents
    ...
    ...
  } = this.props;

  return (
    <Wrapper1>
      {collectionOfComponents.map((oneComponent, index) => (
        <Wrapper2
          ..props
        >
          {oneComponent.component}
        </Wrapper2>
      )}
    </Wrapper1>
  );
};

对于 collectionOfComponents,我将传递以下内容

collectionOfComponents={[
<ComponentOne prop1... prop2... />,
<ComponentOne prop1... prop2... />,
<ComponentTwo prop1... prop2... />
]}

有没有办法确定ComponentTwo 何时通过,以便我可以执行不同的渲染。我不知道该怎么做

编辑 对不起,应该说清楚,但我不想改变地图中的渲染方法我正在寻找一个单独的函数来首先检查componentTwo是否随时存在于数组中(也许) 使用第三类调用两种方法之一,这两种方法将是两种不同的返回方法。然后我会在 render 方法中调用函数

【问题讨论】:

    标签: reactjs ecmascript-6 react-props


    【解决方案1】:
    const isComponentTwo = collectionOfComponents.some(component => component.type.displayName.includes('ComponentTwo'));
    

    如果collectionOfComponents 中至少有一个组件是ComponentTwo,上述将返回true。

    但是,这是不可取的。绝不应将displayNametype 用于生产。这是因为,例如,在缩小过程中,displayNametype 会发生变化,因此您期望的逻辑不会以您期望的方式发生。

    following 声明:

    displayName 字符串用于调试消息。通常,您不需要显式设置它,因为它是从定义组件的函数或类的名称推断出来的。如果您想显示不同的名称以进行调试或创建高阶组件时,您可能需要显式设置它

    更好的解决方案是将某种flagProp 添加到您的组件中。 例如

    decideWhatToDo = () => {
      const { flagPropName } = this.props;
      return flagPropName
        ? this.methodOne()
        : this.methodTwo();
     }
    

    在这两种方法中,您可以决定如果componentTwo 存在或不存在,您要做什么

    【讨论】:

      【解决方案2】:

      也许您可以使用这种方式或类似方式?

          <Wrapper1>
            {collectionOfComponents.map((oneComponent, index) => (
              <Wrapper2
                ..props
              >
                {oneComponent.component instanceof ComponentTwo ? renderWasYouWant : otherRender }
              </Wrapper2>
            )
          </Wrapper1>
      

      【讨论】:

        【解决方案3】:

        当你使用一个组件时,React 会创建一个Element。每个元素都有一个type 属性。类型是component elements 的函数类,或DOM elements 的字符串('button')。

        要查找创建元素的组件,请将元素的类型与创建它的类的函数进行比较:

        const ComponentOne = () => 1;
        const ComponentTwo = () => 2;
        class ComponentThree extends React.Component {
          render() {
            return 3;
          }
        }
        
        const Wrapper = ({ children }) => (
          <div>
          {React.Children.map(children, (El) => {
            switch(El.type) {
              case ComponentOne:
                return <div className="red">{El}</div>;
              case ComponentTwo:
                return <div className="blue">{El}</div>;
              case ComponentThree:
                return <div className="green">{El}</div>;
            }
            
            return null;
          })}
          </div>
        );
        
        ReactDOM.render(
          <Wrapper>
            <ComponentOne />
            <ComponentOne />
            <ComponentTwo />
            <ComponentThree />
          </Wrapper>,
          demo
        );
        .red { background: red; }
        .blue { background: blue; }
        .green { background: green; }
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <div id="demo"></div>

        【讨论】:

        • 或在需要与字符串进行比较的情况下(无论出于何种原因)El.type.name
        • 您应该注意,函数和类的名称在缩小后可能会发生变化。
        • 有没有办法检查componentTwo是否存在于单独的函数中,然后决定做什么?例如如果 componentTwo 存在则调用一个函数,如果不存在则调用另一个函数?
        • 在开关中做任何你想做的事。我已经返回了元素,你调用一个会返回其他东西的函数。
        【解决方案4】:

        使用 indexOf 签入数组:

        collectionOfComponents.indexOf('ComponentTwo') !== -1 // found
        

        【讨论】:

        • 组件不会是唯一的,可能有 5 个 ComponentOne 和两个 ComponentTwo,或者可能有 7ComponentTwo 和 1 个 ComponentOne
        • 无论如何,您只是想知道是否找到了该组件,对吧?
        • 如果您有任何疑问,请告诉我。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-19
        • 1970-01-01
        • 1970-01-01
        • 2013-04-20
        相关资源
        最近更新 更多