у меня странная проблема с React и функцией тайм-аута.
По какой-то причине я хочу, чтобы к букве useEffect
добавлялась строка. Итак, я написал этот код:
const [placeholder, setPlaceholder] = useState < string > ('')
useEffect(() => {
const str = "How may I help you today?";
const letters = Array.from(str);
const addLetterWithDelay = (index: number) => {
if (index < letters.length) {
setTimeout(() => {
setPlaceholder(prevPlaceholder => prevPlaceholder + letters[index]);
addLetterWithDelay(index + 1);
}, 1000); // Delay of 1 second
}
};
addLetterWithDelay(0); // Start adding letters from index 0
}, []);
Проблема в том, что буква устанавливается дважды Таким образом, вывод будет таким: HHooww mmaayy II hheellpp yyououu ttooddaayy?? даже если я проверю с помощью оператора, совпадает ли последний символ заполнителя с буквами [индекс] или нет, он все равно печатает, что это не то же самое, и продолжает выполнение
по сути, ваша функция обновления состояния prevPlaceholder => prevPlaceholder + letters[index]
не является чистой функцией. Он должен быть чистым, чтобы всегда возвращать одно и то же значение при одних и тех же входных данных.
Измените свой useEffect на:
useEffect(() => {
const str = "How may I help you today?";
const letters = Array.from(str);
let timerId: NodeJS.Timeout; // Declare a variable to hold the timeout ID
const addLetterWithDelay = (index: number) => {
if (index < letters.length) {
timerId = setTimeout(() => {
setPlaceholder(prevPlaceholder => prevPlaceholder + letters[index]);
addLetterWithDelay(index + 1);
}, 1000); // Delay of 1 second
}
};
addLetterWithDelay(0); // Start adding letters from index 0
return () => clearTimeout(timerId); // Clear the timeout when the component is unmounted or the useEffect hook re-runs
}, []);
Таким образом, если ваш компонент выполняет повторную визуализацию и перехватчик useEffect вызывается снова, текущий тайм-аут очищается и метод addLetterWithDelay завершается.
Связанное Создание эффекта пишущей машинки в React (с использованием JS)