Доброго времени суток.
Есть 2 хука:
useSessionStorage
const useLocalStorage = (key, initialValue = '') => {
const [value, setValue] = useState(() => {
return sessionStorage.getItem(key) || initialValue;
});
useEffect(() => {
sessionStorage.setItem(key, value);
}, [key, value]);
return [value, setValue];
};
И useFetch
const useFetch = (url) => {
const baseUrl = 'http://localhost:3000';
const [isFetchLoading, setIsFetchLoading] = useState(false);
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const [options, setOptions] = useState({});
const [token] = useSessionStorage('token');
const doFetch = useCallback(
(options = {}) => {
if (!options.method) {
options.method = 'GET';
}
options.headers = {
...options.headers,
'Authorization': token ? `Bearer ${token}` : '',
};
if (options.body) {
options.headers = {
'Content-Type': 'application/json',
...options.headers,
};
}
if (options.body) {
options.body = JSON.stringify(options.body);
}
setOptions(options);
setIsFetchLoading(true);
},
[token]
);
useEffect(() => {
let stopGettingResponseAfterDestroy = false;
if (!isFetchLoading) return;
fetch(`${baseUrl}${url}`, options)
.then((res) => res.json())
.then((data) => {
if (!stopGettingResponseAfterDestroy) {
data.errors ? setError(data) : setResponse(data);
}
})
.catch((err) => {
if (!stopGettingResponseAfterDestroy) {
setError(err);
}
})
.finally(() => {
if (!stopGettingResponseAfterDestroy) {
setIsFetchLoading(false);
}
});
return () => {
stopGettingResponseAfterDestroy = true;
};
}, [url, isFetchLoading, options]);
return [{ isFetchLoading, response, error }, doFetch];
};
Страница с формой:
...
const [token, setToken] = useSessionStorage('token');
const [{ isFetchLoading, response, error }, doFetch] = useFetch('/login');
...
Соответственно на input весит обработчик, который через
setToken устанавливает значение.
Проблема в том, что при вызове хука useFetch, значение токена остается старым.
Например:
Пользователь зашел на страницу, значение в форме пустая строка.
Пользователь ввел данные, значение в sessionStorage изменилось на "somedata", но в хуке useFetch значение все равно старое, т.е. пустая строка. Даже если на прямую получить значение через
sessionStorage.getItem('token')- пустая строка. Но при этом значение в sessionStorage устанавливается корректно, в useEffect я это проверил.
Порядок вызовов:
useFetch (старое значение) => useEffect в useSessionStorage. Почему не происходит еще один рендер useFetch, понять не могу
Могу предположить, что я упускаю важную делать здесь, но пока не могу понять что именно. Подскажите пожалуйста, в чем может быть проблема?
UPD
Поменял useEffect в useSessionStorage
useEffect(() => {
console.log('token useEffect setting value', value);
sessionStorage.setItem(key, value);
setValue(value);
}, [key, value]);
Теперь если в useFetch получать на прямую
sessionStorage.getItem('token'), все будет ок, но через значение из хука все равно старое значение.
Порядок вызовов стал: useFetch => useSessionStorage => useFetch