输入值数组上的 useState 移除焦点
useState on array of input values removes focus
我正在使用 useState
挂钩来更新数组。此数组呈现输入列表。
此代码确实会正确更新 useState
挂钩,但它会在每次按键后从输入中移除焦点。为什么会发生这种情况,我该如何解决?
import React, { useState } from "react";
const Todos = () => {
const [todos, setTodos] = useState(["Read book", "Tidy room"]);
function update(index: number, event: React.ChangeEvent<HTMLInputElement>) {
const newTodos = [...todos];
newTodos[index] = event.target.value;
setTodos(newTodos);
}
return (
<ul>
{todos.map((item, index) => {
return (
<li key={item}>
<input
type="text"
value={item}
onChange={event => update(index, event)}
/>
</li>
);
})}
</ul>
);
};
export default Exercises;
所以问题是您将项目的值用作每个 <li>
的 key
。当您更改输入中的值时,键将更改并做出反应呈现一个全新的 <li>
,而不是仅仅更改已加载到屏幕上的那个。
最简单的解决方案是让每个 Todo 成为一个对象,并给它一个不变的 id
:
import React, { useState } from "react";
interface Todo {
value: string;
id: string;
}
const Todos = () => {
const [todos, setTodos] = useState<Todo[]>([
{
value: "Read book",
id: '1'
},
{
value: "Tidy room",
id: '2'
}
]);
function update(index: number, event: React.ChangeEvent<HTMLInputElement>) {
const newTodos = [...todos];
newTodos[index].value = event.target.value;
setTodos(newTodos);
}
return (
<ul>
{todos.map((item, index) => {
return (
<li key={item.id}>
<input
type="text"
value={item.value}
onChange={event => update(index, event)}
/>
</li>
);
})}
</ul>
);
};
export default Exercises;
我正在使用 useState
挂钩来更新数组。此数组呈现输入列表。
此代码确实会正确更新 useState
挂钩,但它会在每次按键后从输入中移除焦点。为什么会发生这种情况,我该如何解决?
import React, { useState } from "react";
const Todos = () => {
const [todos, setTodos] = useState(["Read book", "Tidy room"]);
function update(index: number, event: React.ChangeEvent<HTMLInputElement>) {
const newTodos = [...todos];
newTodos[index] = event.target.value;
setTodos(newTodos);
}
return (
<ul>
{todos.map((item, index) => {
return (
<li key={item}>
<input
type="text"
value={item}
onChange={event => update(index, event)}
/>
</li>
);
})}
</ul>
);
};
export default Exercises;
所以问题是您将项目的值用作每个 <li>
的 key
。当您更改输入中的值时,键将更改并做出反应呈现一个全新的 <li>
,而不是仅仅更改已加载到屏幕上的那个。
最简单的解决方案是让每个 Todo 成为一个对象,并给它一个不变的 id
:
import React, { useState } from "react";
interface Todo {
value: string;
id: string;
}
const Todos = () => {
const [todos, setTodos] = useState<Todo[]>([
{
value: "Read book",
id: '1'
},
{
value: "Tidy room",
id: '2'
}
]);
function update(index: number, event: React.ChangeEvent<HTMLInputElement>) {
const newTodos = [...todos];
newTodos[index].value = event.target.value;
setTodos(newTodos);
}
return (
<ul>
{todos.map((item, index) => {
return (
<li key={item.id}>
<input
type="text"
value={item.value}
onChange={event => update(index, event)}
/>
</li>
);
})}
</ul>
);
};
export default Exercises;