Я использую следующий компонент для отправки комментариев в своем приложении:
const App = () => {
const [text, setText] = React.useState("");
const send = React.useCallback(() => {
setText("");
console.log("sending", text);
}, [text]);
React.useEffect(() => {
const handler = e => {
switch (e.keyCode) {
case 13: // enter
if (e.shiftKey) {
e.preventDefault();
send();
}
break;
}
}
document.addEventListener("keydown", handler);
return () => document.removeEventListener("keydown", handler);
}, []);
return <div className="App">
<textarea
className="App__text"
value={text}
onChange={e => {
setText(e.target.value);
}} />
<button className="App__send" onClick={send}>send</button>
</div>;
};
здесь работает демонстрация
Это простой текстовое поле и кнопка. При нажатии кнопки или Shift-Enter текст в текстовом поле отправляется на сервер (здесь мы просто console.log
это).
Кнопка работает нормально - введите "hello world"
(или что угодно) нажмите кнопку, и консоль скажет hello world
.
Shift-enter, однако, всегда печатает пустую строку.
Полагаю, я Недоразумение useCallback
. Насколько я понимаю, useCallback
оборачивает вашу функцию. Когда одна из зависимостей изменяется, React заменяет вашу функцию, не меняя функцию-оболочку, поэтому она остается актуальной ссылкой, где бы она ни использовалась. Учитывая, что send
, вызываемый в useEffect
, кажется, имеет начальное значение text
в области видимости, но тот, который используется в onClick
из button
, имеет новейшее значение, мои предположения кажутся неверными.
Я также пробовал добавить text
в качестве зависимости от useEffect
, но
- Я не хочу удалять / создавать / добавлять слушателя при каждом нажатии клавиши и
- Все равно отсутствует последний нажатый символ.
Как сохранить текущую версию моей send
функции внутри другого обратного вызова?