라우팅(Routing)이란 다른 주소에 따라 다른 뷰(화면)를 보여주는 기능
리액트 자체적으로는 이러한 기능이 내장되어있지 않다
(리액트가 Framework가 아닌 Library로 분류되는 이유)
React-router는 React의 라우팅 기능을 위해 가장 많이 사용되는 라이브러리이다
(여러 페이지를 url에 따라 로드하고싶을때 router를 사용)
npm install react-router-dom --save
설치가 완료되면 package.json에 다음과 같이 생성된 것을 확인할 수 있다
Routes.js 파일을 생성해 component를 구현한다
코드
import React from 'react';
import {
BrowserRouter as Router,
Route,
Switch,
} from 'react-router-dom';
import Login from './Pages/Login/Login';
import Main from './Pages/Main/Main';
class Routes extends React.Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/main" component={Main} />
</Switch>
</Router>
)
}
}
export default Routes;
React
를 'react'
에서 import 하기
(react 사용을 위해)
BrowserRouter as Router, Route, Switch
를 'react-router-dom'
에서 import 하기
(router 사용을 위해)
페이지를 로드해줄 Login
, Main
component를 각각의 경로에서 import 해주기
class component 생성
<Route exact path="경로" component={로드할 component} />
/
로 지정하였고/main
으로 지정하였다설치후 index.js 에 router을 사용할 수 있도록 생성한 Routs.js파일을 import 하고
ReactDOM.render에 Routes component 를 넣어준다
코드
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Routes from "./Routes"
ReactDOM.render(
<Routes />,
document.getElementById('root')
);
Route 이동하는 방법은 두 가지가 있는데, 각 용도에 맞춰서 적절히 사용해야 한다
<a>
와 같다 (dom에서 <a>
로 변환된다, a태그를 사용하고 싶지 않다면 Link를 사용하지 않아도 된다)
Link component를 사용하면 별다른 제약없이 바로 이동한다
1. 먼저 Login 파일을 Main 파일과 연력하려는 것이니 Login 파일에 아래와 같이 import하고
import { Link } from 'react-router-dom';
2. 버튼 태그 전체에 걸어준다 (버튼 태그 안 내용에 걸어줄 수 있지만 태그 자체에 걸어주는 것이 좋다)
<Link to="/main">
<button
className={this.changeHandlerBgColor()}
>
로그인
</button>
</Link>
export default Login;
Link를 사용하지 않고, 요소에 onClick 이벤트를 달아서 이동하고 싶은 곳으로 넘기는 방법도 있다
이벤트를 구현해서 this.props
의 history
에 접근해서 이동할 수 있다
받은 history
의 push
메서드에 이동할 path
를 인자로 넘겨주면,
해당 Route
로 이동할 수 있다
1. 먼저 아래와 같이 withRouter
를 'react-router-dom'
을 import 해준다
import { withRouter } from 'react-router-dom';
2-1. withRouter
사용을 위한 함수를 만든다
그냥 외우자.. this.props.history.push('Route.js 파일에 만든 이동 주소');
goToMainup() {
this.props.history.push('/main');
}
2-2. 조건 추가해보기
사용자가 입력한 id에 @, .com, .kr
포함 pw 5자 이상 이어야 main페이지로 넘어갈 수 있게 구현
일단은 되는지 확인이 필요..
constructor() {
super();
this.state = {
userInputId: "",
userInputPw: "",
btnChangeId: "",
btnChangePw: "",
idCheck: ""
};
}
goToMainup() {
//this.props.history.push('/main');
if (this.state.btnChangeId && this.state.btnChangePw && this.state.idCheck) {
this.props.history.push('/main');
} else {
alert('로그인 조건에 맞지 않습니다. 다시 확인해주세요')
}
}
3. withRouter
사용을 위한 onClick
이벤트를 버튼 태그 안에 구현해준다
bind(this)
로 this
가 Login component
라는 것을 확실하게 명시해주기 위해 사용
단어 사전적 의미로 묶어준다고 생각하면 될 것 같다..속해있는 component에
<button
className={this.changeHandlerBgColor()}
onClick={this.goToMainup.bind(this)}
>
로그인
</button>
여기서 bind(this)
는 이벤트를 bind 하는 부분이다
왜 이벤트를 bind 할까?
이걸 하지 않으면 render 메서드에서 this.goToMainup
함수를 호출했을 때,
함수의 this가 window
나 undefined
가 되어버린다
그래서 this가 속해있는 컴포넌트 임을 명확하게 하기 위해 bind(this)
를 사용해야 한다
참고 자료 : 제로초님 블로그
4. export 하는 class 부분을 withRouter로 감싼다
withRouter같이 해당 컴포넌트를 감싸주는 것을 HOC(higher-order component) 이라 한다
HOC는 react 고급 기능이며, 컴포넌트의 공통부분을 구현하는 패턴이라고 생각하면 된다
간단히 말해 HOC는 함수이며, 컴포넌트를 인자로 받고, 컴포넌트를 return하는 함수 이다
참고자료 : 공식문서 HOC
export default withRouter(Login);
주소부분 확인
공식문서 : Sass
설치 : npm install sass --save
Login.js / Main.js 파일도 확장자를 바꿔줘야 한다
// Login.js 파일에서
import './Login.scss';
// Main.js 파일에서
import './Main.scss';
태그 전체에 CSS 속성을 부여하면 전역(global)이 되어 전체 scss 파일에 적용이 된다
클래스 이름이 같아도 마찬가지다
처음에 css가 깨져 왜그런가 했더니 태그자체에 css속성을 받아와서 문제가 발생하였다
Login.js 에서 button 태그 자체에 scss 속성을 걸었더니
Main.js의 button 태그가 Login의 scss를 상속하여
Login.js의 button 태그의 className 으로 scss 속성을 부여하였더니 해결
클래스 생성 함수 수정
changeHandlerBgColor = () => {
return this.state.btnChangeId && this.state.btnChangePw
? "login-button trueColor"
: "login-button falseColor"
}
버튼 scss 수정 - nesting 기능 구현
클래스 이름 2개 일때 nesting 하는 법은 &
를 앞에 붙이는 것 같다
.login-button {
width: 268px;
height: 29.6px;
margin: 8px 40px;
/*background-color:rgba(0,149,246,.3);*/
color:rgba(255,255,255,1);
border-radius: 4px;
border: 0px /*solid transparent*/;
font-size: 14px;
font-weight: 600;
&.trueColor {
background-color: #0562f7;
}
&.falseColor {
background-color:rgba(0,149,246,.3);
}
}
Main.js 의 nav 의 로고 이미지가 Login.js의 로고 이미지 태그의 클래스 이름이 같아서 오류
클래스 이름을 바꿔주니 수정 완료
Main.js 수정한 것 / className을 수정 하였다 혹
.nav-img-logo {
padding: 5px 10px 5px 0px;
}
.nav-text-logo {
padding-left: 11.5px;
border-left: 1.5px solid black;
}
Login.js
.img-logo {
width: 175px;
height: 51px;
margin: 22px auto 30px;
}