event.persist() should be called when using React synthetic events inside an asynchronous callback function

  • REACT_MISSING_EVENT_PERSIST
  • Error
  • Medium
  • react

This rule applies when a React synthetic event is used inside an asynchronous callback function without calling event.persist().

React uses the SyntheticEvent objects to wrap native events. For performance reasons, synthetic events are pooled and reused across multiple native events. To assure consistent usage of the pooled events, React nullifies the properties of synthetic events right after executing an event handler.

If you need to access a synthetic event inside an asynchronous callback function, event.persist() should be called to remove the current event from the pool. Otherwise, an irrelevant value from another event or a null value will be read inside the callback.

Note: The application of this rule is limited to projects using React 16 or below because event pooling was removed in React 17.

Noncompliant Code Example

View with compliant examples side by side
import React from 'react';

export class Hello extends React.Component {
    constructor(props) {
        super(props);
        this.state = { foo: 123 };
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick(event) { // REACT_MISSING_EVENT_PERSIST alarm because 'event' is used inside asynchronous 'setState()' callback.
        this.setState((prevState) => ({
            foo: prevState.foo + event.pageX
        }));
    }
    render() {
        return (
            <div onClick={this.handleClick}>Hello</div>
        );
    }
}

Compliant Code Example

View with noncompliant examples side by side
import React from 'react';

export class Hello extends React.Component {
    constructor(props) {
        super(props);
        this.state = { foo: 123 };
        this.handleClick = this.handleClick.bind(this);
    }
    handleClick(event) {
        event.persist();
        this.setState((prevState) => ({
            foo: prevState.foo + event.pageX
        }));
    }
    render() {
        return (
            <div onClick={this.handleClick}>Hello</div>
        );
    }
}

Version

This rule was introduced in DeepScan 1.32.0.

See

  • SyntheticEvent

  • Event Pooling

  • React Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property pageX on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.

Was this documentation helpful?