React + Firebase auth - «Превышена максимальная глубина обновления» в указанном сценарии c - PullRequest
0 голосов
/ 05 февраля 2020

Я использую Firebase в качестве серверной части для разработки приложения реагирования. Также я использую onAuthStateChanged firebase в качестве наблюдателя для отслеживания изменений состояния пользователя.

App.tsx

const App: React.FC = () => {
    const [authentication, setAuthState] = useState({
        authenticated: !!auth.currentUser,
        initializing: true,
        emailVerified: auth.currentUser ? auth.currentUser.emailVerified : false,
    });

    React.useEffect(() => auth.onAuthStateChanged(user => {
        //TODO need to handle authorization here
        console.log("Auth state changed!", user);
        if (user) {
            setAuthState({
                authenticated: true,
                initializing: false,
                emailVerified:  user.emailVerified
            });
        } else {
            setAuthState({
                authenticated: false,
                initializing: false,
                emailVerified:  false
            });
        }
    }), [setAuthState]);
    if (authentication.initializing) {
        return <div style={{textAlign: 'center', paddingTop: '5%'}}>
            <div style={{display: 'inline-block'}}>
                <Spin/>
            </div>
        </div>
    }

    //TODO if already loggedin navigate without loading
    // if(authentication.authenticated){
    //     return <Redirect to="/nav"/>;
    // }

    return (
        <BrowserRouter>
            <div>
                <Switch>
                    <PublicRoute path="/" component={Welcome} exact isAuthorized={true}/>
                    <PublicRoute path="/login" component={NewLogin} exact isAuthorized={true}/>
                    <PrivateRoute path="/nav" component={NavigationBar} exact isSignedIn={authentication.authenticated}/>
                    <PrivateRoute path="/onboarding" component={OnBoarding} exact isSignedIn={authentication.authenticated}/>
                </Switch>
            </div>
        </BrowserRouter>
    );
};

export default App;

newlogin.tsx

const MyLogin: React.FC = (props: any) => {
    const {getFieldDecorator} = props.form;
    const history = useHistory();
    let [loginState, setLoginState] = useState({
        loading:false,
        loggedIn:!!auth.currentUser
    });


    const buttonStyle = {
        width: '100%',
        height: '40px',
    };

    const handleSuccessfulLogin = () => {
        console.log("coming for successful login");
        message.success("Login Successful!");
        setLoginState({
            loading:false,
            loggedIn:true
        });
    }

    const handleCreate = (e: any) => {
        console.log("coming for signup");
        e.preventDefault();
        props.form.validateFields(['signupName', 'signupMail', 'signupPassword'], (err: any, values: object) => {
            if (!err) {
                console.log('Received values of form:', values);
            }
        });

    }

    const handleLogin = (e: any) => {
        e.preventDefault();
        setLoginState({
            loading: true,
            loggedIn: false
        });
        console.log("coming for login");
        props.form.validateFields(['loginMail', 'loginPassword'], (err: object, values: object) => {
            if (err) {
                return;
            }
            auth
                .setPersistence(session_type)
                .then(() => console.log('state set successfully!!'))
                .catch(function (error) {
                    console.log("Error in setting persistence", error.code, '-', error.message);
                });


            // @ts-ignore
            auth.signInWithEmailAndPassword(values.loginMail, values.loginPassword)
                .then(handleSuccessfulLogin)
                .catch(function (error) {
                    message.error(error.code + ' - ' + error.message);
                    console.log('Sign in failed!', error.code, ' and ', error.message);
                    setLoginState({
                        loading: false,
                        loggedIn: false
                    });
                });
        });

    }



    if (loginState.loading){
        return <div style={{textAlign: 'center', paddingTop: '5%'}}>
            <div style={{display: 'inline-block'}}>
                <Spin/>
            </div>
        </div>
    }

    if(loginState.loggedIn){
        // @ts-ignore
        console.log("Planning to redirect since loggedin: ", auth.currentUser.emailVerified);
        history.push("/nav");
    }
    console.log("--> coming after history push");
    return (
        <div>
            <Form onSubmit={handleLogin}>
                <Form.Item>
                    {getFieldDecorator('loginMail', {
                        rules: [
                            {
                                required: true,
                                message: 'Please enter valid email address',
                                type: 'email'
                            }
                        ]
                    })(<Input
                        prefix={<Icon type="mail"/>}
                        placeholder="Email"
                        style={buttonStyle}
                    />)}
                </Form.Item>
                <Form.Item>
                    {getFieldDecorator('loginPassword', {
                        rules: [
                            {
                                required: true,
                                message: 'Please enter password'
                            }
                        ]
                    })(<Input.Password
                        prefix={<Icon type="lock"/>}
                        type="password"
                        placeholder="Password"
                        style={buttonStyle}
                    />)}
                </Form.Item>
                <Form.Item>
                    <Checkbox style={{float: 'left'}}>Remember me</Checkbox>
                    <a href="" style={{float: 'right'}}>
                        Forgot password
                    </a>
                </Form.Item>
                <Form.Item>
                    <Button type="primary" htmlType="submit" style={buttonStyle}>
                        Login
                    </Button>
                </Form.Item>
                <Form.Item>
                    <Divider>or connect with</Divider>
                    <Divider>
                        <div style={{maxHeight: '3em'}}>
                            <Icon type="google" style={{fontSize: '2.5em', color: '#1890ff'}}/>
                        </div>
                    </Divider>
                </Form.Item>
            </Form>
        </div>
    );
}

export const NewLogin = Form.create()(MyLogin);

С помощью приведенного выше кода я могу аутентифицировать URL и его работоспособность как в состоянии входа в систему, так и в состоянии выхода из системы.

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

Когда я пытаюсь перенаправить через useHistory ловушку, я вижу, что он идет бесконечно зацикливается и в конечном итоге уничтожается реакцией.

Я правильно изменяю состояние и не уверен, где оно идет не так.

Это ошибка, которую я получаю,

enter image description here enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...