【问题标题】:Why enzyme gives "Failed prop type" on a decorated child component为什么酶在装饰的子组件上给出“失败的道具类型”
【发布时间】:2018-12-16 01:17:06
【问题描述】:

如果我使用高阶组件 (HOC) 作为装饰器,即,

@withStyles({})
class Bar extends React.Component { ... }

酶会出现这个错误:

  console.error node_modules/prop-types/checkPropTypes.js:19
    Warning: Failed prop type: The prop `classes` is marked as required in `_class`, but its value is `undefined`.
        in _class

如果我使用函数形式,即,

const Bar = withStyles({})(class extends React.Component { ... });

没有错误。

为什么?

请注意,此警告仅发生在子组件上;请参阅复制步骤中的代码了解我的意思。

复制步骤

package.json:

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "test": "jest"
  },
  "author": "",
  "dependencies": {
    "prop-types": "^15.6.2",
    "react": "^16.4.1",
    "react-dom": "^16.4.1"
  },
  "devDependencies": {
    "babel-jest": "^23.2.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.5",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-16": "^1.1.1",
    "jest": "^23.3.0"
  },
  "babel": {
    "plugins": [
      "transform-class-properties",
      "transform-decorators-legacy"
    ],
    "presets": [
      "env",
      "react"
    ]
  }
}

__tests__/app.test.js:

import Adapter from 'enzyme-adapter-react-16';
import Enzyme from 'enzyme';
import PropTypes from 'prop-types';
import React from 'react';
import { shallow } from 'enzyme';

Enzyme.configure({ adapter: new Adapter() });

const withStyles = styles => Component => class extends React.Component {
  render() {
    return <Component classes={styles} />
  }
}

// This will produce a failed prop type warning:
@withStyles({})
class Bar extends React.Component {
  static propTypes = {
    classes: PropTypes.object.isRequired,
  }

  render() {
    return <div>test</div>;
  }
}

// This will NOT produce a failed prop type warning:
// const Bar = withStyles({})(class extends React.Component {
  // static propTypes = {
    // classes: PropTypes.object.isRequired,
  // }

  // render() {
    // return <div>test</div>;
  // }
// });

class Test extends React.Component {
  render() {
    return <Bar />;
  }
}

it('renders without crashing', () => {
  shallow(<Test />);
  expect(true).toBe(true);
});

运行npm t

有两个代码块:一个带有装饰,另一个(当前已注释掉)带有函数形式。只需注释掉装饰器块并取消注释功能表单块即可测试这两种情况。

这个问题最初是在使用 material-ui 时出现的,我可以确认这两种情况在视觉上呈现相同的 UI。这使我无法使用 withStyles 的装饰器形式。

请注意,我在这里进行了更多调查:https://github.com/airbnb/enzyme/issues/1505

【问题讨论】:

    标签: reactjs jestjs decorator enzyme


    【解决方案1】:

    @babel/plugin-proposal-decorators 需要在@babel/plugin-proposal-class-properties 之前,即在package.json 中:

      "babel": {
        "plugins": [
          "transform-decorators-legacy",
          "transform-class-properties"
        ],
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 2020-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-02
      • 2020-01-22
      相关资源
      最近更新 更多