TypeError: Невозможно прочитать свойство 'scrollIntoView' для null-реагировать.шутить фермент - PullRequest
0 голосов
/ 14 сентября 2018

Использование реакции 16.3.1, шутка 16.3.1, фермента 3.3.0.

В моем компоненте класса React я создал ссылку на ссылку, которую я использую, чтобы убедиться, что при монтировании компонента браузер находится в верхней части страницы.

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

Я пробовал оба метода: shallow и mount , и хотя найденный элемент не равен NULL, он, по-видимому, является реагирующим экземпляром HTMLDivElement, в котором отсутствует метод scrollIntoView.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Уточнение сообщения об ошибке

Использование mount, как в примере кода выше, дает эту ошибку:

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

Использование shallow дает ошибку, указанную выше:

TypeError: Cannot read property 'scrollIntoView' of null


неглубоко

Выпуск

shallow не выполняет DOM-рендеринг, поэтому никогда не будет DOM-узла для вызова scrollIntoView().

Решение

Любой код, который выполняет манипуляции с DOM, должен быть протестирован с использованием полного рендеринга DOM, предоставленного mount.


крепление

"Средой по умолчанию в Jest является среда, подобная браузеру через jsdom" .

"jsdom - это реализация многих веб-стандартов на чистом JavaScript ... [которые] эмулируют [под] достаточное количество подмножеств веб-браузера, чтобы быть полезными для тестирования" .

Выпуск

jsdom реализует большую часть среды браузера, но не все. Особо следует отметить, что этот вопрос не реализует scrollIntoView, поскольку jsdom не выполняет компоновку и, следовательно, не сможет обеспечить точную реализацию .

.

Поскольку jsdom не реализует scrollIntoView, оно будет неопределенным для элементов, предоставленных jsdom.

Решение

рекомендуемый подход от этого разработчика Google заключается в добавлении следующей строки в ваш тестовый код:

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

Эта строка добавит реализацию noop scrollIntoView к jsdom -обеспечиваемому Element.

Для вашего теста вы можете сделать еще один шаг и установить 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
});

Кроме того, Антонио прав, что вам не нужно использовать ReactDOM.findDOMNode(), вы должны иметь возможность использовать this.topOfPageRef.current напрямую:

componentDidMount() {
  this.topOfPageRef.current.scrollIntoView();
}
0 голосов
/ 14 сентября 2018

Ошибка, которую вы получаете, потому что ReactDOM.findDOMNode возвращает вам ноль.

Как говорит React:

Когда компонент рендерится в ноль или ложь, findDOMNode возвращает ноль

также

В большинстве случаев вы можете прикрепить ссылку к узлу DOM и вообще не использовать findDOMNode.

Вы не должны использовать React.findDOMNode

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

но:

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...