Flakelf
@Flakelf

Как правильно делать редирект?

Добрый вечер, интересует, как правильно реализовать редирект в связке React/Redux и React Router

У меня есть контейнер для компонента, контейнер обёрнут в WithRouter и Connect:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';

import RegAuth from '../components/RegAuth';

import {
    regNewUser,
    authUser
} from '../redux/regAuth/actions';

class RegAuthContainer extends Component {
    render() {

        if (this.props.isAuth) {
            this.props.history.push('/personal');
        }

        return <RegAuth regAuthError={this.props.regAuthError} isAuth={this.props.isAuth} authUser={this.props.authUser} regNewUser={this.props.regNewUser} fetching={this.props.fetching} token={this.props.token} />
    }
}

const mapStateToProps = state => {
    return {
        fetching: state.regAuth.fetching,
        isAuth: state.regAuth.isAuth,
        token: state.regAuth.token,
        regAuthError: state.regAuth.regAuthError
    }
}

const mapDispatchToProps = {
    authUser,
    regNewUser
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(RegAuthContainer));


Из хранилища Redux он получает prop isAuth, это false или true, не залогинен или залогинен, соответственно, в render() я проверяю на значение этой prop, вот здесь:

render() {

        if (this.props.isAuth) {
            this.props.history.push('/personal');
        }


Вроде бы всё ок, если isAuth = true, то редиректит на страницу /personal, но смущает следующее:

если в render() обёрнутого в контейнер "тупого" компонента добавить следующий console.log

render() {

        console.log('Rendered');
        

        const { isAuthFormOpened } = this.state;
        const switcherButtonText = isAuthFormOpened ? 'Register now' : 'Already have acc?';

        const { regAuthError, fetching, token } = this.props; // Добавить модный лоадер, если не будет лень

        return (
            <>
                <Header />
                {regAuthError && <Error errorText={regAuthError} />}
                {isAuthFormOpened ? <AuthForm authUserFunc={this.authUser} /> : <RegForm regNewUserFunc={this.regNewUser} />}
                <FormSwitch switcherButtonText={switcherButtonText} FormSwitcher={this.FormSwitcher}/>
                <Footer />
            </>
        )
    }


То он срабатывает, то есть страницу в "умном" компоненте редиректит, то при этом компонент, который уже не нужен - рендерится. Почему так и как это исправить? Баг или фича?
  • Вопрос задан
  • 283 просмотра
Пригласить эксперта
Ответы на вопрос 2
@medin84
software developer
if (this.props.isAuth) {
            this.props.history.push('/personal');
            return null; // Выход из метода
        }

еще есть Redirect в react-router-dom
if (this.props.isAuth) {
            return <Redirect to="/personal" />
        }
Ответ написан
Flakelf
@Flakelf Автор вопроса
Решил следующий образом, в мой экшн authUser

// client\src\redux\regAuth\actions.js

import { history } from '../../index';

export const authUser = userData => dispatch => {
    dispatch({ type: AUTH_REQUEST });
    console.log('Inside checkAuthData action');
    fetch('user/auth', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
    })
    .then(res => res.json())
    .then(res => {
        if (!res.status) {
            return dispatch({
                type: AUTH_FAILURE,
                payload: res.message
            });
        }
        dispatch({
            type: AUTH_SUCCESS,
            payload: res.token
        });
        console.log(history);
        history.push('/personal');
        // localStorage.setItem('token', res.token);
    })
    .catch(err => console.log(err));
}


Импортировал history браузера из корневого файла

// client\src\index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router } from "react-router-dom";
import createBrowserHistory from 'history/createBrowserHistory';
import { Provider } from 'react-redux';

import App from './App.jsx';
import store from './redux/store';

export const history = createBrowserHistory();

ReactDOM.render(
    <Router history={history}>
        <Provider store={store}>
            <App />
        </Provider>
    </Router>, 
    document.getElementById('root'));


И после dispath вызвал метод push у объекта history, какой же я красавчик, будущее веб-разработки нашей необъятной, но тем не менее реквестирую у завсегдатаев варианты, как сделать лучше/оптимальней/красивей/изящней.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы