React合成事件及Test Utilities在Facebook内部进行测试
作者:黎燃
合成事件
boolean bubbles boolean cancelable DOMEventTarget currentTarget boolean defaultPrevented number eventPhase boolean isTrusted DOMEvent nativeEvent void preventDefault() boolean isDefaultPrevented() void stopPropagation() boolean isPropagationStopped() void persist() DOMEventTarget target number timeStamp string type
SyntheticEvent实例将传递给事件处理程序,它是浏览器本地事件的跨浏览器包装器。除了与所有浏览器兼容外,它还具有与浏览器本机事件相同的接口,包括stopPropagation()和preventDefault()。 如果出于某种原因,需要使用浏览器的基础事件,则只需使用nativeEvent属性即可获得它。
从v0.14开始,当事件处理程序返回false时,不再阻止事件气泡。您可以选择改用e.stopPropagation()或e.preventDefault()。 不起作用,this.state.clickEvent 的值将会只包含 null
function onClick(event) { console.log(event); // => nullified object. console.log(event.type); // => "click" const eventType = event.type; // => "click" setTimeout(function() { console.log(event.type); // => null console.log(eventType); // => "click" }, 0); this.setState({clickEvent: event}); // 你仍然可以导出事件属性 this.setState({eventType: event.type}); }
SyntheticEvent被合并。这意味着可以重用SyntheticEvent对象,并且在调用事件回调函数后,所有属性都将无效。出于性能原因,您不能异步访问事件。
number pointerId number width number height number pressure number tangentialPressure number tiltX number tiltY number twist string pointerType boolean isPrimary
Test Utilities
ReactTestUtils可以与您选择的测试框架一起使用,以便轻松测试React组件。在Facebook内部,我们使用Jest轻松实现JavaScript测试。
import ReactTestUtils from 'react-dom/test-utils'; // ES6 var ReactTestUtils = require('react-dom/test-utils'); // ES5 使用 npm 的方式
act()
为断言准备一个组件,包装要呈现的代码,并在调用act()时执行更新。这将使测试更接近React在浏览器中的工作方式。
class Counter extends React.Component { constructor(props) { super(props); this.state = {count: 0}; this.handleClick = this.handleClick.bind(this); } componentDidMount() { document.title = `You clicked ${this.state.count} times`; } componentDidUpdate() { document.title = `You clicked ${this.state.count} times`; } handleClick() { this.setState(state => ({ count: state.count + 1, })); } render() { return ( <div> <p>You clicked {this.state.count} times</p> <button onClick={this.handleClick}> Click me </button> </div> ); } }
不要忘记,触发器DOM事件仅在将DOM容器添加到文档时生效。您可以使用React Testing Library这样的库来减少样板代码。
import React from 'react'; import ReactDOM from 'react-dom'; import { act } from 'react-dom/test-utils'; import Counter from './Counter'; let container; beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); }); afterEach(() => { document.body.removeChild(container); container = null; }); it('can render and update a counter', () => { // 首先测试 render 和 componentDidMount act(() => { ReactDOM.render(<Counter />, container); }); const button = container.querySelector('button'); const label = container.querySelector('p'); expect(label.textContent).toBe('You clicked 0 times'); expect(document.title).toBe('You clicked 0 times'); // 再测试 render 和 componentDidUpdate act(() => { button.dispatchEvent(new MouseEvent('click', {bubbles: true})); }); expect(label.textContent).toBe('You clicked 1 times'); expect(document.title).toBe('You clicked 1 times'); });
将仿真组件模块传递到该方法中后,React模块将填充有效的方法,使其成为虚拟React组件。与通常的渲染不同,组件将变成一个简单的<div>(如果提供了mockTagName,则为其他标记),包括任何提供的子级。
scryRenderedComponentsWithType( tree, componentClass )
这个包提供了一个React渲染器,可以将React组件渲染为纯JavaScript对象,而不依赖DOM或本地移动环境。 这个包的主要功能是在某个时间点返回由React DOM或React Native平台呈现的视图结构(类似于DOM树)的快照,而不依赖浏览器或jsdom。
import TestRenderer from 'react-test-renderer'; function Link(props) { return <a href={props.page}>{props.children}</a>; } const testRenderer = TestRenderer.create( <Link page="https://www.facebook.com/">Facebook</Link> ); console.log(testRenderer.toJSON());
以上就是React合成事件及Test Utilities在Facebook内部进行测试的详细内容,更多关于React合成Test Utilities测试的资料请关注脚本之家其它相关文章!