#reactjs #use-ref
Вопрос:
Я только что изучил useRef и не понимаю, как это на самом деле работает. Например, #1
function Ref() {
const rerenderCount = useRef(0);
useEffect(() => {
rerenderCount.current = rerenderCount.current 1;
});
return <div>{rerenderCount.current}</div>;
}
Здесь useRef выдает тот же вывод, что и useState в следующем коде, #2
function State() {
const [rerenderCount, setRerenderCount] = useState(0);
useEffect(() => {
setRerenderCount(prevCount => prevCount 1);
});
return <div>{rerenderCount}</div>;
}
Но в этом коде #3 значение previousName.current всегда отображает предыдущее значение. Но он настроен на имя.
const [name, setName] = useState("");
const previousName = useRef(null);
useEffect(() => {
previousName.current = name;
}, [name]);
return (
<div className="App">
<input value={name} onChange={(e) => setName(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);
Пожалуйста, кто-нибудь объясните, почему имя на один шаг назад, когда целое число обновляется вовремя. Кроме того, каково использование [name] в useEffect. Без него или без него я получаю тот же результат и подсчет.
Комментарии:
1.
[name]
в использовании эффект-это зависимость. Внутри этого массива вы объявляете список зависимостей, и когда хотя бы одна из них изменяется, выполняется код внутри useEffect. код также запускается при самой первой отрисовке. Таким образом, вы меняетесьpreviousName.current
каждый раз, когда вводите что-то во входной текст. Если вы не добавите какую-либо зависимостьuseEffect
, она будет запускаться каждый раз, когда компонент будет повторно отрисован.2. @Antonio Может, пожалуйста, объяснить, почему perviousName.current всегда стоит на одну букву позади имени? например, когда я набираю «abcd» .. имя = «abcd», но имя.текущий = «abc»? Это внутри useEffect, поэтому, когда имя обновляется, почему useRef не обновляется?
Ответ №1:
В тебе пример previousName
— один шаг позади, потому что при изменении name
состояния компонента рендеринг, useEffect вызывается и previousName
обновляется, но изменения не вызвать нового перевода (useRef не как useState, компонент не будет повторно визуализировать), поэтому вы видите name
обновляется правильно, но previousName
с тем же значением, как и раньше, даже если его значение изменилось. Это связано с тем, что изменение previousName
происходит во время последующего рендеринга, вызванного изменением состояния. Чтобы увидеть его изменение, потребуется дополнительная визуализация. Чтобы избежать такого поведения, вы можете использовать обработчик событий и не полагаться на крючок useEffect.
const handleChange = (text: string) => {
setName(text);
previousName.current = text;
};
return (
<div className="App">
<input value={name} onChange={(e) => handleChange(e.target.value)} />
<div>
My name is {name} and it used to be {previousName.current}
</div>
</div>
);
Комментарии:
1. Теперь я понимаю, спасибо.
2. Если это приемлемо для вас и вы считаете, что это может быть полезно для других людей, пожалуйста, подумайте о том, чтобы принять это.