@BUTURUM

Как правильно отслеживать состояние формы?

У меня проблема: Я написал купу спагетти кода на реакт и теперь из-за этого страдаю. Прежде чем все переписать мне нужно понять где я допустил ошибку из-за которой ничего не работает. Ниже описание функционала который работает не корректно:

Когда пользователь заходить на страницу, приложения подгружает его данные с помощью кастомного хука.

const defaultState = {data : null, error : null, status : EMPTY};

export default function useLoad(loader){
    let [state, setState] = useState(defaultState);

    let load = useEvent(async function(){
        Promise.resolve(loader(...arguments))
            .then(async (respond) => {
                let data = null; if(respond instanceof Response){
                    if(!respond.ok){
                        throw new WebError(respond.status);
                    }
                    if(respond.headers.has('Content-Type') && respond.headers.get('Content-Type').includes('json')){
                        data = await respond.json();
                    }
                } else{
                    data = respond
                }
                setState({...defaultState, data, status : SUCCESS});
            })
            .catch((error) => {
                setState({...defaultState, error, status : ERROR});
            })
        setState({...defaultState, status : LOADING});
    });

    load.overwrite = useCallback((state) => setState({...defaultState, ...state}), [setState]);
    
    return [state, load];
}


Хук принимает калбек условно называемый loader или sender (отличие в том что sender принимает аргументы и отправляет POST запрос), а возвращает состояние и функцию load при вызове которой, хук вызывает loader/sender походу меняя статус состояния "empty" -> "loading"-> "success"/"error". Допускается повторный вызов функции load.

Если пользователь не авторизован загрузить данные не получается, поэтому приложения перенаправляет его на страницу авторизации. Там его ждет две формы (вход/создание аккаунта) обе формы основаны на компоненте формы. Компонент формы под капотом работает через тот самый useLoad. Форма отслеживает изменения состояния через useLayoutEffect и в зависимости от статуса вызывает событие onSuccess или onError.

useLayoutEffect(() => {
    switch(sendState.status){
        case 'success':
            onSuccess(sendState.data); break
        case 'error':
            onError(sendState.error); break
    }
}, [sendState.status]);


В случае с авторизацией после onSuccess пользователя перенапрявять обратно на главную страницу, а состояния загрузки перезаписывается насильно через overwrite.

А в чем же собственно проблема? Да в том что если в компоненте формы для отслеживания состояния загрузки заменить useLayoutEffect на useEffect или прямой вызов второго калбека (назовём его manager) в useLoad, то все идёт в черту!

В результате этого маленького изменения состояния приложения (не загрузки) будет меняться два раза в два разных рендера: сначала адреса станицы, потом состояния загрузки. Это ломает всю логику и не позволяет сделать нормальную переадресацию.

Пожалуйста помогите, сижу над этой ошибкой уже второй день!
  • Вопрос задан
  • 133 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы