Основные сценарии, когда синтаксис функционального обновления все еще необходим, - это когда вы находитесь в асинхронном коде. Представьте себе, что в useEffect
вы делаете какой-то вызов API, а когда он заканчивается, вы обновляете какое-то состояние, которое также может быть изменено другим способом. useEffect
будет закрыт по значению состояния во время начала эффекта, что означает, что к моменту завершения вызова API состояние может быть устаревшим.
Пример ниже имитирует этот сценарий, когда нажатие кнопки запускает два разных асинхронных процесса, которые завершаются в разное время. Одна кнопка выполняет немедленное обновление счета; одна кнопка запускает два асинхронных приращения в разное время без использования синтаксиса функционального обновления (кнопка «Наивный»); последняя кнопка запускает два асинхронных приращения в разное время с использованием синтаксиса функционального обновления (кнопка Robust).
Вы можете поиграть с этим в CodeSandbox, чтобы увидеть эффект.
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
function App() {
const [count, setCount] = useState(1);
const [triggerAsyncIndex, setTriggerAsyncIndex] = useState(1);
const [triggerRobustAsyncIndex, setTriggerRobustAsyncIndex] = useState(1);
useEffect(
() => {
if (triggerAsyncIndex > 1) {
setTimeout(() => setCount(count + 1), 500);
}
},
[triggerAsyncIndex]
);
useEffect(
() => {
if (triggerAsyncIndex > 1) {
setTimeout(() => setCount(count + 1), 1000);
}
},
[triggerAsyncIndex]
);
useEffect(
() => {
if (triggerRobustAsyncIndex > 1) {
setTimeout(() => setCount(prev => prev + 1), 500);
}
},
[triggerRobustAsyncIndex]
);
useEffect(
() => {
if (triggerRobustAsyncIndex > 1) {
setTimeout(() => setCount(prev => prev + 1), 1000);
}
},
[triggerRobustAsyncIndex]
);
return (
Count: {count}
);
}
const rootElement = document.getElementById("root");
ReactDOM.render( , rootElement);
Другой возможный сценарий, в котором могут потребоваться функциональные обновления, - это если несколько эффектов обновляют состояние (даже если синхронно). Как только один эффект обновляет состояние, другой эффект будет смотреть на устаревшее состояние. Этот сценарий кажется мне менее вероятным (и в большинстве случаев кажется плохим выбором дизайна), чем асинхронные сценарии.
Используйте запятую вместо своего "И":
UPDATE exercises
SET times_answered = times_answered + 1,
av_answeringTime = av_answeringTime + ( (av_answeringTime / (times_answered) ) + ?) * (times_answered + 1)
WHERE name = ?
Попробуйте что-то вроде этого ...
UPDATE exercises
SET times_answered = times_answered + 1,
av_answeringTime = av_answeringTime + ( (av_answeringTime / (times_answered) ) + ?) * (times_answered + 1)
WHERE name = ?
The SQL UPDATE syntax is:
UPDATE table SET
column1 = value1,
column2 = value2
WHERE condition
Instead of the AND you need a comma