#reactjs #react-hooks #use-effect
Вопрос:
В своих функциональных компонентах React я пытаюсь использовать пользовательский usePrevious для получения/сравнения предыдущего значения моего объекта контекста. Однако, похоже, что он всегда имеет последнее значение, а не предыдущее значение. Ниже приведен мой код. Пожалуйста, дайте мне знать, если я делаю здесь что-то не так.
function MyHeaderComponent(props) {
const [myPref, setMyPref] = React.useContext(MyContext);
const prevPreferences = usePrevious(myPref.preferences);
useEffect(() => {
console.log("prevPreferences : " prevPreferences); // Prints current context object, instead of the previous one
// I want to call myInfo only if prevPreferences is not the same as myPref.preferences (i.e. current)
}, [myPref]);
function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
});
return ref.current;
}
const myInfo = async () => {
setMyPref(myPref);
}
return (
<>
<div>
Some JSX
</div>
</>
)
}
export default withRouter(withStyles()(MyHeaderComponent));
function MyPreferences(props) {
const [myPref, setMyPref] = React.useContext(MyContext);
// somewhere in code
setMyPref(myPref);
}
Комментарии:
1. Почему этот пользовательский крючок определен внутри компонента? Каждый раз вы получаете совершенно новый крючок, который вряд ли поможет сохранить какую-либо историю.
2. Я попытался воспроизвести его. Я не мог codesandbox.io/s/boring-cray-z628s?file=/src/App.js . Пожалуйста, предоставьте свой минимальный воспроизводимый образец.
3. @jonrsharpe — Даже после создания отдельного файла/крючка я сталкиваюсь с той же проблемой…
Ответ №1:
Эта реализация useLatest
(которая, кстати, не должна находиться внутри компонента) не копирует значение в поле ссылки, она просто присваивает ссылку.
Я бы поспорил myPref.preferences
, что он будет внутренне изменен (вместо того, чтобы быть переназначенным новому объекту), поэтому вы всегда видите одно и то же значение.
Комментарии:
1. Значит, нет никакого способа получить старое значение ?
2. Либо сделайте так, чтобы ваш
useLatest
крючок скопировал значение (например, LodashcloneDeep
), либо убедитесь, что вы всегда присваиваете ему новое значение и не изменяете его внутренне.
Ответ №2:
Я думаю, проблема в том, что вы используете хук usePrevious внутри другого функционального компонента. Не могли бы вы попробовать создать файл для крючка usePrevious.
usePreviousState.js
function usePrevious(value, initialValue) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
if (ref.current === undefined amp;amp; initialValue !== undefined) {
return initialValue;
}
return ref.current;
}
Комментарии:
1. Спасибо… пробовал это…. та же проблема…