Я хотел бы знать, как получить обновленный labelRef
внутри функции, а именно: inputBlur()
import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [inputValue, setInputValue] = useState("Type...");
const [labelWidth, setLabelWidth] = useState();
const labelRef = useRef();
const inputChange = e => {
setInputValue(e.target.value);
setLabelWidth(labelRef.current.offsetWidth);
};
const inputBlur = e => {
const trimmed = e.target.value.trim();
if (trimmed) {
setInputValue(trimmed);
} else {
setInputValue("Type...");
}
setLabelWidth(labelRef.current.offsetWidth);
};
useEffect(() => {
setLabelWidth(labelRef.current.offsetWidth);
}, []);
return (
<div className="App">
<p>Type below to see if input and div is the same width</p>
<div ref={labelRef}>{inputValue}</div>
<br />
<input
value={inputValue}
onChange={e => inputChange(e)}
onBlur={e => inputBlur(e)}
style={{ width: `${labelWidth}px` }}
/>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Чтобы объяснить этот пример немного, есть поле ввода, которое меняет свою ширину назаполнение div
тем же текстом. В настоящее время, это не работает правильно, когда поле ввода пусто, сопровождаемое событием onblur
. Поле ввода должно быть заполнено значением по умолчанию useState
, "Type..."
, но ширина поля ввода равна 0.
Я вижу проблему в том, что в функции inputBlur
после запуска setInputValue
,строка labelRef.current.offsetWidth
по-прежнему отражает старый элемент, поскольку он еще не визуализировал этот элемент.
Здесь приведена ссылка на codesandbox этого примера, чтобы попытаться воспроизвести эту проблему.
Моя проблема возникла из-за непонимания потока реакции. Мне нужно захватить событие после того, как useState
обновил элемент со значением по умолчанию, а затем вычислил ширину.
Примечание: я не хочу, чтобы ввод автоматически заполнял пустое поле ввода значением по умолчаниюЗначение пока в фокусе. Он должен быть заполнен в случае onBlur()
.