升级到React 17后,addEventListener无意中添加了selectionchange事件到文档中

问题描述 投票:0回答:1

我正在使用jest v27和@testing-library/react v12,我升级到React 17,有addEventListener无意中添加到文档中的selectionchange事件。我根本没有使用这个活动。

最小可重现示例:

// App.test.tsx

import { render } from "@testing-library/react";
import App from "./App";

test("App", () => {
  it("test", async () => {
    const addSpyDoc = jest.spyOn(window.document, "addEventListener");
    render(<App />);

    // this expect would fail and show that it is called with 
    // 1: "selectionchange", [Function bound dispatchDiscreteEvent], false
    // 2: "selectionchange", [Function bound dispatchDiscreteEvent], true
    
   expect(addSpyDoc).not.toHaveBeenCalled();
  });
});


// App.tsx 

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
    </div>
  );
}

// index.tsx

import { render } from "react-dom";
import App from "./App";

const rootElement = document.getElementById("root");
render(<App />, rootElement);

以下是配置文件和package.json

// tsconfig.json

{
  "include": ["*"],
  "compilerOptions": {
    "baseUrl": ".",
    "lib": ["dom", "es2015"],
    "jsx": "react-jsx",
    "isolatedModules": true,
    "moduleResolution": "node",
    "module": "ESNext",
    "target": "ES6",
    "resolveJsonModule": true
  }
}

// .babelrc.json

{
  "sourceType": "unambiguous",
  "presets": [
    "@babel/preset-env",
    "@babel/preset-typescript",
    "@babel/preset-react"
  ],
  "plugins": []
}

// jest.config.ts

import type { Config } from "@jest/types";

export const sharedConfig: Config.InitialOptions = {
  verbose: true,
  preset: "ts-jest",
  testEnvironment: "jsdom",
};

// package.json

  "dependencies": {
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "ts-node": "^10.9.1",
    "ts-jest": "^27.1.3",
    "@babel/core": "^7.17.9",
    "@babel/preset-env": "^7.23.3",
    "@babel/preset-react": "^7.23.3",
    "@babel/preset-typescript": "^7.23.3",
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "12.1.5",
    "@types/jest": "^27.4.1",
    "@types/node": "^17.0.25",
    "@types/react": "17.0.55",
    "@types/react-dom": "17.0.23",
    "babel-loader": "^8.2.4",
    "jest": "27.5.1",
    "typescript": "4.5.3"
  },
  "scripts": {
    "test": "jest test --env=jsdom"
  },

为了更容易运行,这里有React 17和16的两个沙箱。在v16中,没有额外的事件添加到文档中。

https://codesandbox.io/s/jest-react-testing-library-forked-8cygdn?file=/src/App.test.tsxReact 17

https://codesandbox.io/s/jest-react-testing-library-forked-r4k6zh?file=/src/App.test.tsxReact 16

这种行为是预期的吗?添加这个非故意的选择更改事件的原因是什么?

非常感谢您的帮助!

reactjs jestjs addeventlistener react-testing-library jsdom
1个回答
0
投票

我遇到了类似的问题,并通过调试器查看 ReactDOM 的 listenToNativeEvent 实现有一个特殊情况,它添加了一个事件气泡侦听器。这种情况是针对“selectionchange”事件且 rootContainerElement 不是文档节点时的情况。

selectionchange 事件是一个浏览器事件,当用户在文档中进行选择时触发,并且我相信它不会在 DOM 树中冒泡(浏览器直接在文档上触发它)。因此,即使根容器不是文档节点,React 组件也必须正确监听选择更改事件。

我还没有使用react18进行测试,看看行为是否不同,但似乎是有意为之,而且我不确定我们是否应该在使用react17并模拟addEventListenerCall时在测试中考虑这种行为。

© www.soinside.com 2019 - 2024. All rights reserved.