刚开始学习 React 一周前,卡在调试上,每次输入键后输入字段都失去焦点。

huangapple go评论56阅读模式
英文:

Just started learning React a week ago, stuck on debugging why the input field unfocused after each key entry

问题

以下只是一个简化的示例,重现了这个问题。

function MultiplierBox() {
const [a, setA] = useState([1.0, 2.2])
function updateA(index, newValue) {
const newArray = [...a];
newArray[index] = newValue;
setA(newArray);
}
function Row({ a, index }) {
function handleA(event) {
const newValue = parseFloat(event.target.value)
updateA(index, newValue)
}
return
}
return (

{a}

);
}
```

我尝试过的方法:

  • 使用单个值而不是数组(有效)
  • 检查CSS样式规则
  • 创建问题的简化版本

我期望的结果:

  • 输入字段保持焦点

<details>
<summary>英文:</summary>

Below is just a simplified dummy example that reproduces this problem. 

function MultiplierBox() {
const [a, setA] = useState([1.0, 2.2])
function updateA(index, newValue) {
const newArray = [...a];
newArray[index] = newValue;
setA(newArray);
}
function Row({ a, index }) {
function handleA(event) {
const newValue = parseFloat(event.target.value)
updateA(index, newValue)
}
return <input type="number" value={a[index]} onChange={handleA} />
}
return (<div className="MultiplierBox">
{a}
<Row a={a} index={0} />
<Row a={a} index={1} />
</div>);
}


What I tried:
- using a single value instead of arrays (works)
- checked the css style rules
- created a simplified version of the problem

What I expect:
- the input field stays focused

</details>


# 答案1
**得分**: 1

You have defined your `Row` component *inside* of the `MultiplierBox` component. That means that every time MultiplierBox renders, a brand new Row function is created. It may have the same text as the old one, but as far as react can tell, it's a different type of component. So react unmounts the old row and mounts the new one. A newly-mounted input does not have focus.

The fix is to define all your components just once, at the top level. You will need to modify the Row component so that `updateA` is a prop that's passed down:
```javascript
function Row({ a, index, onChange }) {
  function handleA(event) {
    const newValue = parseFloat(event.target.value);
    onChange(index, newValue);
  }
  return <input type="number" value={a[index]} onChange={handleA} />;
}

function MultiplierBox() {
  const [a, setA] = useState([1.0, 2.2]);
  function updateA(index, newValue) {
    const newArray = [...a];
    newArray[index] = newValue;
    setA(newArray);
  }

  return (
    <div className="MultiplierBox">
      {a}
      <Row a={a} index={0} onChange={updateA} />
      <Row a={a} index={1} onChange={updateA} />
    </div>
  );
}
英文:

You have defined your Row component inside of the MultiplierBox component. That means that every time MultiplierBox renders, a brand new Row function is created. It may have the same text as the old one, but as far as react can tell, it's a different type of component. So react unmounts the old row and mounts the new one. A newly-mounted input does not have focus.

The fix is to define all your components just once, at the top level. You will need to modify the Row component so that updateA is a prop that's passed down:

function Row({ a, index, onChange }) {
  function handleA(event) {
    const newValue = parseFloat(event.target.value);
    onChange(index, newValue);
  }
  return &lt;input type=&quot;number&quot; value={a[index]} onChange={handleA} /&gt;;
}

function MultiplierBox() {
  const [a, setA] = useState([1.0, 2.2]);
  function updateA(index, newValue) {
    const newArray = [...a];
    newArray[index] = newValue;
    setA(newArray);
  }

  return (
    &lt;div className=&quot;MultiplierBox&quot;&gt;
      {a}
      &lt;Row a={a} index={0} onChange={updateA} /&gt;
      &lt;Row a={a} index={1} onChange={updateA} /&gt;
    &lt;/div&gt;
  );
}

huangapple
  • 本文由 发表于 2023年3月4日 02:41:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定