【问题标题】:React.js: How to get all props component expects?React.js:如何获得所有 props 组件的期望?
【发布时间】:2018-01-21 14:50:03
【问题描述】:

我开始对 React.js 应用程序进行单元测试,我面临的挑战之一是确定组件正确安装它所需的所有道具。是否有任何实用程序可以检查成功安装组件所需的一切?此外,这些道具的数据类型以适当地初始化它们以进行组件渲染。

就像我的组件之一是使用传播 {...props} 运算符从父级获取道具。父母也使用传播运算符获得这些,然后添加一些额外的道具并将其传递给孩子。这让我很难获得组件期望的所有道具。有什么合法的方法可以获取道具列表吗?

【问题讨论】:

  • 也许组件应该总是能够正确挂载。也许如果您为组件提供 defaultProps ,您可以避免麻烦。在这种情况下,毫无疑问需要正确安装哪些道具,因为组件总是正确安装。最好的问题是没问题:-)。希望我有所帮助
  • hmm.. 但问题是能够设置 defaultProps 我需要知道组件需要的道具!这基本上就是问题所在。
  • 这听起来像是 JSDoc (docblock) 的绝佳案例,如下所述:github.com/reactjs/react-docgen/issues/98

标签: reactjs redux react-redux enzyme jestjs


【解决方案1】:

对于unit testing,这完全可以让您的父组件只检查它添加到其子组件的属性。因为在单元测试中,您只是测试特定单元的功能。在这种情况下,您要检查您的父组件是否将所有需要的属性添加到其子组件并传递它需要的所有其他属性(无论它们是什么)。

您同时测试您的子组件并检查其功能。

要检查两个或多个组件是否正确交互,您应该使用E2E/functional testing。在这种情况下,您将测试工作应用程序的一些功能部分。如果您对组件交互有一些问题,它们会弹出。

【讨论】:

    【解决方案2】:

    解决这个问题的一种方法是使用装饰器。我知道他们还没有完全在这里,至于现在你可能需要使用打字稿或类似的东西。但它是对所述问题的解决方案,它允许您装饰并将任何所需的信息附加到组件的属性中。以下是打字稿中的示例:

    @PropContainer("Textbox")
    export class TextboxProps
    {
        @Prop(PropertyType.Mandatory)
        public propA: string;
    
        @Prop(PropertyType.Optional)
        public propB?: number;
    }
    

    【讨论】:

      【解决方案3】:

      一个有趣的任务。

      我开始:

      import React from "react";
      import * as PropTypes from "prop-types";
      
      function Hello(props) {
        const { boo, foo } = props;
        return (
          <div>
            <h1>{boo}</h1>
            <h2>{foo}</h2>
          </div>
        );
      }
      
      Hello.propTypes = {
        boo: PropTypes.string,
        foo: PropTypes.number
      };
      
      export default Hello;
      

      我发现这篇文章https://blog.jim-nielsen.com/2020/proptypes-outside-of-react-in-template-literal-components/有功能:

      /**
       * Anytime you want to check prop types, wrap in this
       * @param {function} Component
       * @param {Object} propTypes
       * @return {string} result of calling the component
       */
      function withPropTypeChecks(Component) {
        return props => {
          if (Component.propTypes) {
            Object.keys(props).forEach(key => {
              PropTypes.checkPropTypes(
                Component.propTypes,
                props,
                key,
                Component.name
              );
            });
          }
          return Component(props);
        };
      }
      

      然后我又写了一篇:

      const getPropsInfo = (component) => {
        const result = {};
        const mock = Object.keys(component.propTypes).reduce(
          (acc, p) => ({ ...acc, [p]: Symbol() }),
          {}
        );
        const catching = (arg) => {
          const [, , prop, type] = `${arg}`.match(
            /Warning: Failed (.*) type: Invalid .* `(.*)` of type `symbol` supplied to.*, expected `(.*)`./
          );
          result[prop] = type;
        };
        const oldConsoleError = console.error.bind(console.error);
        console.error = (...arg) => catching(arg);
        withPropTypeChecks(component)(mock);
        console.error = oldConsoleError;
        return result;
      };
      

      我选择 Symbol 作为不太期望的类型。

      并称它为:

      const propsInfo = getPropsInfo(Hello);
      console.log(propsInfo);
      

      结果我得到:{boo: "string", foo: "number"}

      P.S.:我还没有在其他类型上测试过。只是为了好玩! :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-02
        • 2014-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多