使用反应16.3.1,开胃菜16.3.1,酶3.3.0。

在我的React Class组件中,我创建了一个react ref,以确保在安装组件时浏览器位于页面顶部。

class PageView extends React.Component {

  constructor(props) {
    super(props);
    this.topOfPageRef = React.createRef();
  }

  componentDidMount() {
    ReactDOM.findDOMNode(this.topOfPageRef.current).scrollIntoView();
  }

  render(){
    const { x } = this.props;

    return (
      <React.Fragment>
        <div className="main-wrapper" ref={this.topOfPageRef}>
         Top
        </div>
        )}
      </React.Fragment>
    );
  }
}


所有这些在浏览器中都可以正常运行,但是在我的酶测试中失败了。

我的测试很简单,它只是尝试渲染组件。

  it('should render component correctly', () => {
    const props = {
      ...defaultProps,
    };
    const wrapper = mount(<PageView {...props} />);
    expect(wrapper).toMatchSnapshot();
  });


TypeError: Cannot read property 'scrollIntoView' of null

我尝试了浅方法和安装方法,虽然找到的元素不为null,但它似乎是HTMLDivElement的react实例,缺少了scrollIntoView方法。

最佳答案

错误消息说明

像上面的示例代码中那样使用mount会出现此错误:

TypeError: _reactDom2.default.findDOMNode(...).scrollIntoView is not a function

使用shallow会给出上面列出的错误:

TypeError: Cannot read property 'scrollIntoView' of null





问题

shallow不会进行DOM渲染,因此将永远不会在其上调用scrollIntoView()的DOM节点。



任何执行DOM操作的代码都必须使用mount提供的完整DOM渲染进行测试。



安装

"The default environment in Jest is a browser-like environment through jsdom"

"jsdom is a pure-JavaScript implementation of many web standards...[that] emulate[s] enough of a subset of a web browser to be useful for testing"

问题

jsdom实现了许多浏览器环境,但并未实现所有功能。此问题特别值得注意的是,由于scrollIntoView does not do layout and would therefore not be able to provide an accurate implementation,因此它未实现jsdom

由于jsdom不实现scrollIntoView,因此在jsdom提供的元素上将是未定义的。



recommended approach from this Google dev将以下行添加到测试代码中:

Element.prototype.scrollIntoView = () => {};

该行将向scrollIntoView提供的jsdom添加Element的noop实现。

为了进行测试,您可以更进一步,将scrollIntoView设置为spy以确保它被调用:

it('should render component correctly', () => {
  const props = {
    ...defaultProps,
  };
  Element.prototype.scrollIntoView = jest.fn();  // set scrollIntoView to a spy
  const wrapper = mount(<PageView {...props} />);
  expect(wrapper).toMatchSnapshot();
  expect(Element.prototype.scrollIntoView).toHaveBeenCalled();  // PASSES
});




另外,Antonio是正确的,您不需要使用ReactDOM.findDOMNode(),应该可以直接使用this.topOfPageRef.current

componentDidMount() {
  this.topOfPageRef.current.scrollIntoView();
}

关于javascript - TypeError:无法读取null的属性'scrollIntoView'- react 。笑话 enzyme ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52331990/

10-10 23:18