4

I'm handling the onPaste event in a React application. The problem I'm having is that the value of the element isn't updated until after the paste event has finished and thus I'm unable to determine whether the pasted data overwrites the existing value or extends upon the existing value.

In the following snippet, if you have the word "cheese" copied into your clipboard and freshly run the snippet for both of the below scenarios:

  1. Paste the word at the end of the existing value, so that it becomes "123cheese".
  2. Paste the word over the existing value, so that it becomes "cheese".

In both, the logged value will be equal to "123" and it's not possible to determine how the value has changed with the value property alone.

class Example extends React.Component {
  handlePaste(e) {
    const clipboardData = e.clipboardData.getData('text');
    const value = e.target.value;
    
    console.log("Pasted:", clipboardData);
    console.log("Value:", value);
  }
  
  render() {
    return <input defaultValue="123" onPaste={this.handlePaste.bind(this)} />;
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById('example')
)
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>
<p>tl;dr: Please refer to the instructions above the snippet.</p>

Now I'm well aware that a potential solution would be to delay the code I'm wanting to execute within the handler until after the event has finished, but this feels hacky and unnecessary:

class Example extends React.Component {
  handlePaste(e) {
    const clipboardData = e.clipboardData.getData('text');
    ((target) => {
      setTimeout(() => {
        const value = target.value;
    
        console.log("Pasted:", clipboardData);
        console.log("Value:", value);
      }, 100)
    })(e.target);
  }
  
  render() {
    return <input defaultValue="123" onPaste={this.handlePaste.bind(this)} />;
  }
}

ReactDOM.render(
  <Example />,
  document.getElementById('example')
)
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="example"></div>

How can I get the modified value (or what the value will become) within an onPaste event handler?

James Donnelly
  • 126,410
  • 34
  • 208
  • 218

0 Answers0