2
votes

I have a component UsernameInput, which is managed via redux store. I want to get input value when onCut event triggered.

import React from 'react'
import connect from 'react-redux'
import {validateUsername} from '../actions'

const UsernameInput = ({username, validateUsername}) => {
    
    return (

        <div className="form-group">
            <input type="text" className="form-control"
            onChange={e => validateUsername(e.target.value)}
            onPaste={e => validateUsername(e.clibboardData.getData('Text'))}
            onCut={e => validateUsername(e.currentTarget.value)}
            defaultValue={username}
            />
        </div>
    );
}

export default connect((state) => state.validateUsername, {validateUsername})(UsernameInput);

That is if the value of input is "blablabla", and after cutting the whole text validateUsername function should be called with empty string, and if the half of the input was cut, then it should be called with parameter like "blab". onCut e.currentTarget.value is returning the value of the input field before cut, but I want it to return the actual input value.

How to do it?

3
Why not store the input value in a state? - johannchopin
@johannchopin I am using redux, and dispatching input value. - Asad Ganiev

3 Answers

2
votes

I found a unique solution. Instead of catching onChange, onPaste and onCut events, I am just catching onKeyUp event:

<input type="text" className="form-control"
onKeyUp={e => validateUsername(e.currentTarget.value)}
defaultValue={username}
/>

and it is working for all events.

0
votes

Add a state hook

Obviously I have a simple example here, you should integrate something like this in your form component. Perhaps even replacing the useState with useReducer for more complex forms.

The idea is that you have a state. This state has a setter function. When the state is set the component re-renders. When the component re-renders you get access to the value anywhere in the component via the state.

const myInput = (props) => {
  const [cutValue, setCutValue] = React.useState();
  
  console.log(cutValue); // this will start as undefined and then when setCutValue is triggered you will have the result

  return <input type="text" onCut={e => {setCutValue(e.target.value)}/>
}
0
votes

So onCut is invoked before the browser has handled the default behavior of cutting which explains what you are seeing as far as the value is concerned. https://developer.mozilla.org/en-US/docs/Web/API/Element/cut_event

Some point after onCut is called, onChange is also called which reflects the actual inputs value after the cut. If knowing whether or not you cut is important you can set something in state for onCut and then handle it appropriately in the onChange.

export default function App() {
  const [isCut, setIsCut] = React.useState(false);
  const [preCut, setPreCut] = React.useState("");
  return (
    <div className="App">
      <input
        onCut={(e) => {
          setIsCut(true);
          setPreCut(e.currentTarget.value);
        }}
        onChange={(e) => {
          console.log("isCutting", isCut);
          console.log("precut", preCut, "I changed", e.currentTarget.value);
          setIsCut(false);
          setPreCut("");
        }}
      />
    </div>
  );
}

Example here https://codesandbox.io/s/dark-paper-k2pnr?file=/src/App.tsx