输入值数组上的 useState 移除焦点

Eva*_*nss 1 react-hooks

我使用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;
Run Code Online (Sandbox Code Playgroud)

小智 5

所以问题是您使用该项目的值作为keyfor every <li>。当您更改输入中的值时,键将发生变化,并且反应会呈现一个全新的值<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;

Run Code Online (Sandbox Code Playgroud)