简体   繁体   English

改变 event.target.value(在 React 中)的后果是什么?

[英]What are the consequences of mutating event.target.value (in React)?

Let's say we are building custom input component.假设我们正在构建自定义输入组件。

In this component, as an example let's say we want to change the value from a string to a number在这个组件中,例如,假设我们要将值从字符串更改为数字

const CustomInputComponent = ({ onChange, ...rest }) => {
  const onChangeHandler = (event)=>{
    // What are the consequences of doing this?
    event.target.value = parseInt(event.target.value, 10);
    onChange(event);
  }
  return <input type="text" onChange={onChangeHandler} />
}

What are the consequences of directly mutating event.target.value like this?像这样直接变异event.target.value会有什么后果?

What are the consequences of directly mutating event.target.value like this?像这样直接变异 event.target.value 会有什么后果?

They're exactly what you would expect: the value of the input gets changed to the new value.它们正是您所期望的:输入的值被更改为新值。

Granted, if you assume that the user enters a numeric value, there won't be any noticeable output - because although you're overwriting the event.target.value from say the string "1" to the number 1 , that will get coerced back to a string inside the input, because input values can only ever be strings.当然,如果您假设用户输入了一个数值,则不会有任何明显的 output - 因为尽管您将event.target.value从字符串"1"覆盖为数字1 ,但这将被强制执行回到输入中的字符串,因为输入值只能是字符串。

But, if the user types anything else, you'll get strange-looking - and I can only assume unintended - consequences.但是,如果用户键入其他任何内容,您会看起来很奇怪——我只能假设意外的后果。 See the demo below where I've set up a simple render of your component (with an onChange function prop that does nothing - this is just to illustrate your component without it crashing and makes no difference here), and observe for yourself the consequences (spelled out below the snippet).请参阅下面的演示,其中我设置了您的组件的简单渲染(使用onChange function 道具,它什么都不做 - 这只是为了说明您的组件没有崩溃并且在这里没有任何区别),并自己观察后果(在代码段下方详细说明)。

 const CustomInputComponent = ({ onChange, ...rest }) => { const onChangeHandler = (event)=>{ // What are the consequences of doing this? event.target.value = parseInt(event.target.value, 10); onChange(event); } return <input type="text" onChange={onChangeHandler} /> } const App = () => <CustomInputComponent onChange={()=>{}} />; ReactDOM.render(<App/>, document.getElementById("root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

  • as previously observed, if you enter the character "1" , it gets displayed as expected.如前所述,如果您输入字符"1" ,它将按预期显示。
  • if you then enter a non-numeric character, it won't appear at all.如果你然后输入一个非数字字符,它根本不会出现。 This is because the when you type "a" here, say, the event.target.value is "1a" , and parseInt("1a", 10) is equal to 1 .这是因为当您在此处键入"a"时,例如, event.target.value"1a" ,并且parseInt("1a", 10)等于1 ( parseInt is different from coercion via Number in that it will read whatever numeric values it can from the start of the string and just stop processing when it hits a character it can't parse.) So the value gets set to 1 , the same as it was before. parseInt与通过Number的强制不同,它会从字符串的开头读取它可以读取的任何数值,并在遇到无法解析的字符时停止处理。)因此该值设置为1 ,相同和以前一样。
  • if you enter any non-numeric content, including simply by deleting the above (to leave event.target.value as the empty string), or by resetting to the start and entering a non-numeric character, the output will become NaN .如果您输入任何非数字内容,包括简单地删除上述内容(将event.target.value保留为空字符串),或通过重置开始并输入非数字字符,output 将变为NaN That's because strings which don't even begin with a numeric character, including the empty string, return NaN ("not a number", although confusingly that value has type number ) when parseInt is used.这是因为当使用parseInt时,甚至不以数字字符开头的字符串(包括空字符串)返回NaN (“不是数字”,尽管令人困惑的是该值的类型number )。

So no, you don't want to do this.所以不,你不想这样做。

The only value - assuming it's acceptable to you for things to go so wonky as this with non-numeric input - seems to be to allow consumers of this prop to provide an onChange which directly acts on numbers without having to convert from string to number inside the function itself.唯一的价值 - 假设你可以接受 go 的事情,因为这与非数字输入一样不稳定 - 似乎是允许这个道具的消费者提供一个onChange直接作用于数字而不必从字符串转换为内部数字function 本身。 This seems an incredibly weak benefit to me, for the following reasons:这对我来说似乎是一个非常微弱的好处,原因如下:

  1. your component is an <input type="text" /> without even an inputmode="numeric" to suggest numeric input is required.您的组件是一个<input type="text" />甚至没有inputmode="numeric"来建议需要数字输入。 There's absolutely no reason to expect users won't want to type non-numeric characters here - and even if you give it a label and description that make abundantly clear only numbers are allowed, users are still going to do it (if only by committing typos), and expect the input to appear.绝对没有理由期望用户不想在这里输入非数字字符 - 即使你给它一个 label 和描述清楚地只允许数字,用户仍然会这样做(如果只是通过提交拼写错误),并期望输入出现。 You want to give an error message in these circumstances, not force the input to change it to something else.您想在这些情况下给出错误消息,而不是强制输入将其更改为其他内容。

  2. even if this is supposed to be a numeric input, anyone with any experience of developing with HTML and Javascript knows full well that event.target.value is always a string.即使这应该是一个数字输入,任何有任何使用 HTML 和 Javascript 开发经验的人都知道event.target.value始终是一个字符串。 Even if they want to do numeric things with that string, they'll fully expect to have to do the conversion to a number themselves.即使他们想用那个字符串做数字的事情,他们也完全期望必须自己转换成数字。

  3. if despite the above, you really want to provide an event object to the onChange function prop which has a number for it's target value, you can do it without mutating the existing event object, for example like this:如果尽管如此,您确实想向onChange function 道具提供一个事件 object ,该道具有一个数字作为其目标值,您可以在不改变现有事件 ZA8CFDE6331BD59EB2AC96F8911C4B 的情况下执行此操作,例如:

const modifiedEvent = { ...event, { target: { ...event.target, value: parseInt(event.target.value, 10) }}};
onChange(modifiedEvent);

And well I find that line of code kind-of disgusting - although you can probably make it less horrendous, perhaps with some helper libraries that are specifically designed for immutable "updates" like this.好吧,我发现那行代码有点恶心-尽管您可能可以使它不那么可怕,也许可以使用一些专门为像这样的不可变“更新”而设计的帮助程序库。 But for me really it's yet another reason, if one were really needed, not to do this.但对我来说,这确实是另一个原因,如果真的需要,不要这样做。 Having said that, even the above is much better than the direct mutation of event.target.value that you're asking about.话虽如此,即使上述内容也比您所询问的event.target.value的直接突变好得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM