useNavigate
React와 TS를 사용해서 프로젝트를 진행하고 있다.
클릭없이 페이지를 이동할 일이 생겨서 당연하게 useHistory를 사용했는데
띠용.... 이게 무슨일이야 해서 찾아봤더니 리액트 v6부터는 useHistory 대신에 useNavigate을 사용하라고 한다.
React Router | Upgrading from v5
Declarative routing for React apps at any scale
reactrouter.com
공식문서를 보면 useHistory를 사용했을 때랑 비교하면서 사용법이 잘 나와있다. 컴포넌트로도 사용할 수 있는 것 같다.
useNavigate를 사용하면 .push 나 .go와 같은 함수가 필요없이 그냥 인자값에 따라서 알아서 함수가 적용되는것 같았다.
const navigate = useNavigate();
navigate('/login/nickname');
그래서 함수 사용해서 변수 선언해주고, 그 안에 이동할 경로를 적어서 사용해줬다.
useNavigate & useLocation
그런데 이번엔 파라미터를 같이 넘겨하는 상황이 생겨서 찾아보니 뒤에 파라미터를 추가해주라고 한다.
원래는 파라미터를 하나만 보내기 때문에 아무생각 없이
navigate('/login/nickname', {
email
});
이렇게 보내려고 했다. 그런데 TS 에러가 났고,
(property) email: string
'{ email: string; }' 형식의 인수는 'NavigateOptions' 형식의 매개 변수에 할당될 수 없습니다. 개체 리터럴은 알려진 속성만 지정할 수 있으며 'NavigateOptions' 형식에 'email'이(가) 없습니다.ts(2345)
state 를 추가해서 코드를 변경해줬더니 에러가 사라졌다. state를 필수로 적어줘야한다.
찾아보니까 useNavigate에는 두개의 인자가 올 수 있다.
replace
navigate('/' , {replace : true})
이렇게 작성해주면 뒤로가기 히스토리가 남지 않는다. false가 온다면 뒤로가기가 가능하다.
state
navigate('/' , {state : 'params'})
이렇게 작성하면 해당 페이지로 state를 가지고 이동한다.
그래서 다시 다음과 같이 수정해줬다. 객체도 전달 가능하다.
navigate('/login/nickname', {
state: email
});
그리고 이제 파라미터를 받을 때는 useLocation을 사용해서 얻을 수 있다.
const location = useLocation();
const email = location.state;
TS가 들어가다 보니 매우 헤맸다...ㅎ 평소처럼 작성하면 자꾸 타입이 없다고 그러고 할당할 수 없다고 unkwon이라고 그러고 해서 TS에 대해서 아직 모르는게 너무 많다고 생각했고 제대로 공부해야겠다는 생각을 했다.
+)
navigate를 사용할 때 파라미터를 객체로 보내는 걸로 수정할 일이 생겼다.
navigate('/login/nickname', {
state: {
email: data.email,
socialLoginType: data.socialLoginType
}
});
그런데 계속 useLocation()을 사용해서 받아오는 부분에서 오류가 발생했고, email 변수에 접근을 하려고 해도 location.state가 unknown이라 할당 할 수 없다고 나왔다.......하
'unknown' 형식에 'email' 속성이 없습니다
그래서 열심히 삽질하면서 이것저것 해보다가,,, 구세주같은 블로그를 발견했다....
[TypeScript] react-router v6 type: unknown 오류
타입스크립트에서 react-router-dom v6로 작업 중이다. react-router의 useLocation을 이용해서 state 값을 넘겨주려고 했는데 type unknown 오류가 났다. useLocation에 인터페이스를 지정해도 오류가 나고 location
velog.io
react-router-dom v6부터는 location.state가 unknown으로 사용된다는 것이고, 이를 해결 하기 위해 as로 타입을 명시해주면 된다고 한다.
최종 결과
파라미터 보내기
navigate('/login/nickname', {
state: {
email: data.email,
socialLoginType: data.socialLoginType
}
});
인터페이스 선언
export interface NicknameProps {
email: string;
socialLoginType: number;
}
파라미터 받기
const state = location.state as NicknameProps;
const { email } = state;
const { socialLoginType } = state;
'개발 공부 > React' 카테고리의 다른 글
[React+TS] React에서 비로그인처리, PrivateRoute사용하기 (0) | 2022.11.15 |
---|---|
[React+TS+StyledComponent] 사이드바 만들기 + 외부 클릭시 닫히는 기능 (0) | 2022.06.28 |