我有一个基本的任务列表应用程序,它使用户能够向任务列表添加项目。单击“添加项目”按钮时,我将在列表底部插入新行。该行包含一个空文本字段,用户可以在其中输入其任务名称。我想将焦点放在push()
一旦进入数组。我知道如果该字段已经存在,如何使用ref
设置焦点,但是对于动态添加的字段,我似乎无法弄清楚。我该怎么办?
这是我的代码:
const tasks = [array_of_task_objects];
const [state, setState] = React.useState({tasks: tasks});
const newTask = {title: ''};
const addTask = () => {
let newTasks = [...state.tasks];
newTasks.push(newTask);
setState({...state, tasks: newTasks});
// Now, set focus in the input field...(how?)
};
其他地方:
<button onClick={addTask}>Add Task</button>
<ul>
{
state.tasks.map(task => {
return(
<li><input value={task.title}></li>
);
})
}
</ul>
您可以在第一次呈现任务输入时使其本身成为焦点。
const Task = ({value}) => {
const ref = useRef(null);
useEffect(() => if (ref.current) {ref.current.focus()}, [ref.current])
return <li><input ref={ref} value={value} /></li>
}
如果您一次只安装一个,这将起作用。例如,如果您在初始状态下渲染了多个输入,则可以引入shouldTakeFocus
属性。然后,将效果限制为仅在shouldTakeFocus
为true时运行。
一种方法是让ref始终引用最后一个文本框,然后运行一个效果,当tasks
更新时,该效果将焦点放在最后一个元素上。这是一个示例的外壳,基本上应该可以使您到达那里:
export default function App() {
const [tasks, setTasks] = useState([newTask]);
const lastRef = useRef(null);
useEffect(() => {
if (lastRef.current)
lastRef.current.focus();
}, [tasks]);
return (
<div className="App">
{tasks.map((task, i) => (
<>
<input key={i} ref={i === tasks.length - 1 ? lastRef : undefined} />
<br />
</>
))}
<button
onClick={() => {
setTasks(tasks => [...tasks, newTask]);
}}
>
Add
</button>
</div>
);
}