dwjohnston
dwjohnston

Reputation: 11870

Console log statements on React event handler causes synthetic event warnings

Code Sandbox here: https://codesandbox.io/s/0olpzq7n3n

It's some pretty straight forward code:

const Form = ({ form, updateForm }) => {
  const handleChange = (event, value) => {
    console.log(event, value);
    console.log(event.target.name, event.target.value);

    const newForm = { ...form, ...{ [event.target.name]: event.target.value } };
    updateForm(newForm);
  };

  return (
    <form>
      <input
        name="value1"
        value={form.value1}
        onChange={event => handleChange(event)}
      />
    </form>
  );
};

const Form1 = connect(
  state => ({ form: state.form1 }),
  dispatch => ({ updateForm: newForm => dispatch(updateFormOne(newForm)) })
)(Form);

function Home() {
  return (
    <div>
      <h2>👋 Welcome to the Home route</h2>
      <Form1 />
    </div>
  );
}

If you edit the form input in this scenario it gives these warnings:

Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property `nativeEvent` on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See (shortend URL that StackOverflow doesn't like). 

If I remove those console log statements, the warning disappears.

What's happening here?

Upvotes: 3

Views: 4426

Answers (1)

Matt Carlotta
Matt Carlotta

Reputation: 19772

You're trying to console.log() an asynchronous synthetic event that is removed by the time the callback is executed. If you wish to to persist the event, then use event.persist().

Using event.persist(), you can see all of the event properties:

ispatchConfig: Object
_targetInst: FiberNode
nativeEvent: InputEvent
type: "change"
target: <input name="value1" value="this is form a1"></input>
currentTarget: null
eventPhase: 3
bubbles: true
cancelable: false
timeStamp: 2926.915000000008
defaultPrevented: false
isTrusted: true
isDefaultPrevented: function () {}
isPropagationStopped: function () {}
_dispatchListeners: null
_dispatchInstances: null
isPersistent: function () {}
<constructor>: "SyntheticEvent"

More information about synthetic events can be found here and here.

However, if you already know what you want from the event, then you can destructure its properties like so:

const handleChange = ({ target: { value, name } }) => {
    console.log(name, value);

    const newForm = { ...form, [name]: value };
    updateForm(newForm);
  };

Upvotes: 4

Related Questions