auth-service.js에는 Firebase Authentication을 처리하는 로직이 들어있다.
// auth-service.js
class AuthService {
constructor(app) {
this.firebaseAuth = getAuth(app);
}
logout() {
// 로그아웃
}
emailSignIn(email, password) {
// 이메일로 회원가입
}
checkedEmailPassword(email, password) {
// 로그인 시 가입한 정보와 일치하는지 확인 후 home으로 이동
}
회원가입과 로그인, 로그아웃을 담당하는 class인데 여기서 문제가 발생했다. checkedEmailPassword() 함수에서 서버로부터 데이터를 받아온 뒤, 가입한 정보가 로그인할 때 입력한 정보와 같으면 페이지 이동을 해야했다.(같지 않으면 switch 문을 이용해 error.code에 따라 각각의 에러메시지를 띄우도록 했다.)
Authentication을 처리하는 로직을 class로 작성한 이유는 login, signin 컴포넌트 뿐만 아니라 profile, post 컴포넌트에서도 이 데이터가 필요하기 때문에 class를 사용한 것이고, function 컴포넌트로 작성하자니 코드 양이 많아질 것 같았다.. 최대한 class 컴포넌트를 사용하되, 페이지 이동도 가능하도록 구현하고 싶어서 class 컴포넌트에서 사용할 수 있는 navigation이 있을까 찾아봤다.
참고한 링크 :
https://dbstndi6316.tistory.com/366
https://github.com/remix-run/react-router/issues/8146
// in hocs.js
function withNavigation(Component) {
return props => <Component {...props} navigate={useNavigate()} />;
}
function withParams(Component) {
return props => <Component {...props} params={useParams()} />;
}
// in BlogPost.js
class BlogPost extends React.Component {
render() {
let { id } = this.props.params;
// ...
}
}
export default withParams(BlogPost);
깃허브 질문에 달린 답변 중에 위 코드로 시도해봤으나 내 코드(아래 코드)는 index.js에서 firabaseApp을 넘겨 받아야하기 때문에 에러가 발생했다..
// index.js
const authService = new AuthService(firebaseApp);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ThemeProvider theme={theme}>
<App authService={authService} />
</ThemeProvider>,
);
다른 방법이 없을까 열심히 찾아봤는데 class 컴포넌트에서 navigate를 사용하는 방법보다는 function 컴포넌트에서 사용하는 걸 권장한다는 글이 있었던 것 같다. 비록 깊지 않은 지식을 갖고 있지만 꼭 해결하고 싶어서 내 코드를 열심히 뜯어봤다. 깃허브에 달린 답변을 힌트 삼았다.
// Login.jsx
const navigator = useNavigate();
authService.checkedEmailPassword(navigator, userEmail, userPassword);
navigator 변수에 useNavigate() 함수를 할당해 checkedEmailPassword() 함수의 인자로 전달하는 방법을 시도했다. 확인 결과, 문제없이 잘 동작했다. 더 나은 방법이 있을 수도 있겠지만 현재로서는 최선의 방법으로 해결했다!