Home > OS >  Why does trim() not work for setting a string within an object (related to type, not the nature of t
Why does trim() not work for setting a string within an object (related to type, not the nature of t

Time:05-11

I could not figure this out. Eventually created a code sandbox to try and isolate the issue and found that even stripped down, the issue persists.

I have a controlled input that should not allow the space character. e.target.value.trim() correctly trims the space characters when the state is stored as a string but allows them when the state is part of an object.

So this works correctly:

const [primitivestring, setPrimitiveString] = useState("");
...

<input
        value={primitivestring}
        onChange={(e) => {
          const trimmedValue = e.target.value.trim();
          setPrimitiveString(trimmedValue);
        }}
      />

But this does not:

const [newuserState, setnewuserState] = useState({ email: "" });
...
 
<input
        placeholder="Email address/Username"
        id="email"
        type="email"
        value={newuserState.email}
        onChange={(e) => {
          const trimmedValue = e.target.value.trim();
          console.log({
            trimmedValue,
            trimmedValueLength: trimmedValue.length
          });
          setnewuserState({ ...newuserState, email: trimmedValue });
        }}
      />

Link to code sandbox: https://codesandbox.io/s/sharp-hugle-7cw6tv?file=/src/App.js:353-772

Why is this happening?

Another quirk (and secondary question) - the character counter for the 'buggy' input does not update when a space character is typed BUT it does update the count (including the space characters) when a non-space character is eventually typed. Why?

Update - As per the accepted answer, the issue was to do with type="email" and entirely unrelated to how the value in question is being stored in state. Still unclear why this issue is as it is. This thread touches on it: https://github.com/facebook/react/issues/6368 - if anybody has more info or a clear explanation, I would love to know more.

CodePudding user response:

The type="email" is throwing things off. Emails cannot have spaces, so it looks like React, when it sees an input field of type email where the value has a space, does not fire its onChange handler because the input is invalid.

Remove the type="email" and it'll work as expected.

the character counter for the 'buggy' input does not update when a space character is typed BUT it does update the count (including the space characters) when a non-space character is eventually typed. Why?

Same reason - if the value has a space, it's not a valid email, so the handler doesn't fire.

function App() {
  const [primitivestring, setPrimitiveString] = React.useState("");
  const [newuserState, setnewuserState] = React.useState({ email: "" });
  return (
    <div className="App">
      <h1>Sample input component</h1>
      <h2>Spaces should be trimmed but are not</h2>
      <input
        placeholder="Email address/Username"
        id="email"
        value={newuserState.email}
        onChange={(e) => {
          const trimmedValue = e.target.value.trim();
          setnewuserState({ email: trimmedValue });
        }}
      />
    </div>
  );
}

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

  • Related