티스토리 뷰

history.push와 Redirect차이점이 궁금해진 이유

 개인 프로젝트에 HOC를 적용하며 props.history와 Redirect의 차이점이 무언지 궁금해졌다.

현재 로그인 유무에 따라 접근을 제한하기 위한 HOC를 만들고 있다.

예를 들어 로그인 페이지는 로그인 전은 접근이 가능하도록 하고 로그인 후는 로그인 페이지에 접근하려 할 경우 기본 페이지로 다시 돌아가게 작동을 하려하는 상황이다.

 

1. Redirect를 사용한 경우

    function Authentication(props : any){
        useEffect(() => {
            if(option){                
                (async () => {
                    const request = await axios.get('/user')
                        .then((response : AxiosResponse) => response.data)
                        .catch((err : AxiosError) => err);
                        
                    if(pageCase === pageCaseLogined 
                        && request["useremail"] 
                        && request["message"] === "success"){
                        <Redirect to="/"/>
                    }else if(pageCase === paceCaseUserPatch
                        && request["message"] === "none jwt"){
                            <Redirect to="/"/>
                        }
                })();
            }
        }, []);
        return (
            <Component/>
        );
    }

 위의 코드는 HOC로써 컴포넌트를 input받아 user의 로그인 유무에 따라 접근을 제한하기 위한 의도로 작성했다.

server에 user의 상태를 확인 후 로그인이 되어있는 경우 로그인/회원가입 페이지에 접근하지 않도록 할 의도로 Redirect를 사용하였다.

 하지만 위의 코드는 의도와 상관 없이 항상 input된 컴포넌트를 반환했다.

 어떻게 컴포넌트의 접근을 제한알까 생각해 보다가 history.push를 사용해보았다.

2. history.push를 사용한 경우

    function Authentication(props : any){
        useEffect(() => {
            if(option){                
                (async () => {
                    const request = await axios.get('/user')
                        .then((response : AxiosResponse) => response.data)
                        .catch((err : AxiosError) => err);
                        
                    if(pageCase === pageCaseLogined 
                        && request["useremail"] 
                        && request["message"] === "success"){
                        props.history.push('/');
                    }else if(pageCase === paceCaseUserPatch
                        && request["message"] === "none jwt"){
                            props.history.push('/');
                        }
                })();
            }
        }, [props.history]);
        return (
            <Component/>
        );
    }

위의 코드는 history.push를 사용한 코드이며 Redirect만 바뀌었다.

history.push를 사용하니 의도대로 코드가 동작이 되었다. (history.replace를 사용해도 의도대로 작동된다.)

 

여기서 Redirect와 history.push의 차이점이 무엇인가 궁금해졌다.

 

history

 - history객체는 react-router의 부가기능이며 아래와 같은 기능 등을 탑재한다.

 - 특정 경로로 이동 => (history.push)

 - 뒤로가기 기능     => (history.goBack)

 - 페이지 이탈 방지 => (history.block)

history 객체를 출력한 모습

 - 컴포넌트에서 router에 직접 접근을 할 수 있도록 해준다.

 - history.push와 history.replace가 있는데 둘 모두 페이지를 이동시켜주는 기능을 하지만, push는 history라는 스택의 가장 위에 방문 기록을 쌓는 것이고, replace는 방문 기록을 쌓지않고 가장 위의 history를 현재 경로로 변경한다.

 

Redirect

 - to로 입력된 경로로 페이지가 redirection된다.

 - 기본적으로 history.replace와 같은 동작을 하며, push옵션을 줄 경우 history.push와 같이 작동한다.

 - Redirect의 interface는 다음과 같이 정의되어 있다.

export interface RedirectProps {
    to: H.LocationDescriptor;
    push?: boolean;
    from?: string;
    path?: string;
    exact?: boolean;
    strict?: boolean;
}

 - to

   ▸ 필수적인 값이며 redirection할 URL경로를 입력한다.

   ▸ 문자열을 입력하는 방법과 객체를 입력하는 방법이 있다.

   ▸ 문자열로 입력할 경우 URL경로를 그대로 작성하면 된다.

   ▸ 객체로 입력할 경우 다음과 같이 정의되어 있다.

//Redirect의 to에 입력할 수 있는 객체에 대한 정의
export interface LocationDescriptorObject<S = LocationState> {
    pathname?: Pathname;
    search?: Search;
    state?: S;
    hash?: Hash;
    key?: LocationKey;
}

 - push

   ▸ push는 redirect할 때 history에 새 항목을 push한다.

   ▸ boolean값으로써 Redirect에 history.push와 같이 작동하게 하려면 push를 입력하면 된다.

 - from

   ▸ redirection할 경로 이름이다.

   ▸ string형태로 입력한다

   ▸ <Redirect> 내부를 렌더링 할 때 위치를 일치시키는 데만 사용할 수 있다.

 - exact 

   ▸ Route의 exact와 같다.

   ▸ 입력된 경로로 시작 되는 모든 경로와 매칭되도록 한다.

   ▸ boolean값 이다. 

   ▸ from과 같이 사용해야 된다.

 - strict

   ▸ Route의 strict와 같다

   ▸ 지정한 경로만 지나가도록 한다.

   ▸ boolean값이다

   ▸ from과 같이 사용해야 된다.

   

현재의 내용만 가지고는 Redirect와 history.push의 어떤것이 차이나는지 잘 모르겠다.

history.push('/')를 이용하여 작동할 수 있다면, <Redirect push to='/' />도 동일하게 작동이 되어야 하지 않을까?

console.log로 Redirect와 history를 출력해보았다.

위의 객체가 Redirect, 아래의 객체가 history이다.

객체의 내용은 분명히 다르다.

 

history객체의 location가 정의된 내용을 보면 아래와 같은데 익숙한 패턴이다.

Redirect의 to에 객체로 정의하는 경우의 LocationDescriptorObject interface와 동일한 모양이다.

다른점이 있다면 key의 데이터가 존재한다.

그렇다면 Redirect의 to를 객체형태로 입력하고 key값을 입력해 주어야 history.push와 동일한 효과를 낼 수 있을 것 같은데(확실하지 않음,,,) key값은 페이지를 이동할 계속 변하므로 알아낼 방법이 없다.

 

현재의 상황에서 Redirect를 어떻게 작성을 해야 history.push와 동일하게 작동이 되도록 할 수 있을지는 잘 모르겠다.

애초에 다른 객체지만 Redirect에서도 history에 push를 할 수 있는 기능이 있고, 분명히 방법이 존재할 것이라고 생각되지만, 이 부분은 좀더 살펴봐야 겠다.

 

참고 : https://reactrouter.com/web/guides/quick-start

 

React Router: Declarative Routing for React

Learn once, Route Anywhere

reactrouter.com

 

'front-end > react' 카테고리의 다른 글

[React] react router  (0) 2021.06.04
Redux  (0) 2021.05.23
[React] Lifecycle과 useEffect hook  (0) 2021.04.30
[React공식문서읽기] JSX이해하기  (0) 2021.04.22
[React공식문서읽기] 고차 컴포넌트(HOC, Higher Order Component)  (0) 2021.04.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함