У тебя проблема связана с гидратацией — это когда серверный HTML отличается от клиентского из-за того, что данные из localStorage подгружаются уже после рендера.
Вот как это можно обойти:
1. Вариант с useEffect остаётся нормальным. Ты просто сначала задаёшь дефолтное состояние, а потом в useEffect подтягиваешь данные из localStorage. Да, данные сначала будут пустыми, но зато не будет ошибки гидратации.
const [dataForm, setDataForm] = useState<IDataForm>({
lastName: '',
firstName: '',
middleName: '',
dateOfBirth: '',
numberPhone: '',
email: '',
amount: 1000,
term: 5,
checkbox: false,
});
useEffect(() => {
const storedData = getStoredData<IDataForm>(StorageKeys.GENERAL_INFO);
if (storedData) {
setDataForm(storedData);
}
}, []);
Если критично, чтобы форма не показывалась до загрузки данных, то просто добавь условие:
if (!dataForm) {
return null; // можно спиннер или что-то такое показать
}
2. Если хочешь, чтобы данные подгружались сразу без лишнего рендера, то данные надо либо уже отдавать с сервера (например, через getServerSideProps, если у тебя Next.js), либо хардкодить их в начальное состояние, но это не всегда удобно.
3. Ещё вариант — проверить на клиентской стороне. Например:
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
if (!isClient) return null; // или показывай что-то временное
return (
<YourFormComponent dataForm={dataForm} />
);
Этот способ тоже рабочий и позволяет избежать ошибки гидратации. В общем, всё сводится к тому, чтобы подгружать данные только после того, как React знает, что он на клиенте, и не пытаться смешивать логику клиента и сервера.