英文:
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 (
);
}
```
我尝试过的方法:
- 使用单个值而不是数组(有效)
- 检查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 <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>
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论