[英]Generator function inside useCallback is returning same values in react, How to solve this?
我正在 React 中创建待办应用程序,对于我正在使用生成器 function 的任务 ID。但是这个生成器 function 每次都给出值 0 而不是递增值。我认为问题的原因是 useCallback() 钩子,但我是不确定解决方案是什么。如何解决这个问题?我在这里提供代码:
import DateAndDay, { date } from "../DateAndDay/DateAndDay";
import TaskList, { TaskProps } from "../TaskList/TaskList";
import "./ToDo.css";
import Input from "../Input/Input";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
function ToDo() {
const [inputShow, setInputShow] = useState(false);
const [valid, setValid] = useState(false);
const [enteredTask, setEnteredTask] = useState("");
const [touched, setTouched] = useState(false);
const [tasks, setTasks] = useState<TaskProps[]>(() => {
let list = localStorage.getItem("tasks");
let newdate = String(date);
const setdate = localStorage.getItem("setdate");
if (newdate !== setdate) {
localStorage.removeItem("tasks");
}
if (list) {
return JSON.parse(list);
} else {
return [];
}
});
const activeHandler = (id: number) => {
const index = tasks.findIndex((task) => task.id === id);
const updatedTasks = [...tasks];
updatedTasks[index].complete = !updatedTasks[index].complete;
setTasks(updatedTasks);
};
const clickHandler = () => {
setInputShow((prev) => !prev);
};
const input = inputShow && (
<Input
checkValidity={checkValidity}
enteredTask={enteredTask}
valid={valid}
touched={touched}
/>
);
const btn = !inputShow && (
<button className="add-btn" onClick={clickHandler}>
+
</button>
);
function checkValidity(e: ChangeEvent<HTMLInputElement>) {
setEnteredTask(e.target.value);
}
function* idGenerator() {
let i = 0;
while (true) {
yield i++;
}
}
let id = idGenerator();
const submitHandler = useCallback(
(event: KeyboardEvent) => {
event.preventDefault();
setTouched(true);
if (enteredTask === "") {
setValid(false);
} else {
setValid(true);
const newtitle = enteredTask;
const newComplete = false;
const obj = {
id: Number(id.next().value),
title: newtitle,
complete: newComplete,
};
setTasks([...tasks, obj]);
localStorage.setItem("setdate", date.toString());
setEnteredTask("");
}
},
[enteredTask, tasks, id]
);
useEffect(() => {
const handleKey = (event: KeyboardEvent) => {
if (event.key === "Escape") {
setInputShow(false);
}
if (event.key === "Enter") {
submitHandler(event);
}
};
document.addEventListener("keydown", handleKey);
return () => {
document.removeEventListener("keydown", handleKey);
};
}, [submitHandler]);
useEffect(() => {
localStorage.setItem("tasks", JSON.stringify(tasks));
}, [tasks]);
return (
<div className="to-do">
<DateAndDay />
<TaskList tasks={tasks} activeHandler={activeHandler} />
{input}
{btn}
</div>
);
}
export default ToDo;
useCallBack()的用于记忆function发送给它的结果。 这个结果永远不会改变,直到依赖数组的任何变量/函数改变它的值。 因此,请检查传递的依赖项是否正确,或者它们是否在您的代码中发生了变化(或提供此文件的所有代码)。 我的猜测之一是将 Valid state 作为依赖项添加到数组
这是因为您在idGenerator
之外调用了 idGenerator,所以只有在重新呈现组件时才会生成它,在您的情况下……只有一次。
在 useCallback 中调用它,并在每次触发事件时调用它:
// wrap this on a useCallback so it gets memoized
const idGenerator = useCallback(() => {
let i = 0;
while (true) {
yield i++;
}
}, []);
const submitHandler = useCallback(
(event: KeyboardEvent) => {
event.preventDefault();
let id = idGenerator();
// ... rest of logic
},
[enteredTask, tasks, idGenerator]
);
如果您在事件处理程序之外使用生成的id
,请将 ID 存储在 state 中,如下所示:
const idGenerator = useCallback(() => {
let i = 0;
while (true) {
yield i++;
}
}, []);
const [id, setId] = useState(idGenerator());
const submitHandler = useCallback(
(event: KeyboardEvent) => {
event.preventDefault();
let newId = idGenerator();
setId(newId)
// ... rest of logic
},
[enteredTask, tasks, id, idGenerator]
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.