GitHub: https://github.com/Jaeminst/react-shoppingmall
참고 했던 블로그 링크
App.js파일에서 react-route-dom 라이브러리의 NavLink
를 가져오고 <NavLink></NavLink>
를 아래와 같이 작성.
react-router-dom 라이브러리의 NavLink
는 isActive
라는 상태정보가 들어있어서 콜백으로 삼항연산을 통하여 문자열로 출력되게 만들었다.
/* App.js */
import './App.css';
import { BrowserRouter, NavLink } from 'react-router-dom';
import Home from './Pages/Home'
function App() {
return (
<div className="App">
<BrowserRouter>
<nav className='black-nav'>
<NavLink className={({isActive}) => "nav-link" + (isActive? "a" : "")} to='/'>Home</NavLink>
</nav>
</BrowserRouter>
</div>
)
}
export default App;
다음은 App.css파일에서 className으로 스타일링을 해주었다.
/* App.css */
.black-nav {
background: black;
width: 100%;
display: flex;
color: white;
padding: 20px;
font-weight: 500;
font-size: 20px;
box-sizing: border-box;
}
.nav-link {
color: white;
padding: 20px;
font-size: 20px;
font-weight: 400;
margin: 5px;
}
.nav-linka {
color: aqua;
padding: 20px;
font-size: 20px;
}
먼저 터미널에서 라이브러리를 추가하고
$ yarn add styled-components
그런다음 App.js에 먼저 import를 해준다.
import styled from "styled-components";
수정을 진행 했던 코드는 아래와 같다.
App.css파일과 import는 없애고 필요한 css 코드만 js파일에 넣어주었다.
/* App.js */
import styled from "styled-components";
/* import './App.css'; */
import { BrowserRouter, NavLink } from 'react-router-dom';
import Home from './Pages/Home'
const AppDiv = styled.div`
text-align: center;
`
const BlackNav = styled.div`
background: black;
width: 100%;
display: flex;
color: white;
padding: 20px;
font-weight: 500;
font-size: 20px;
box-sizing: border-box;
`
const NavStyle = styled(NavLink)`
color: white;
padding: 20px;
font-size: 20px;
font-weight: 400;
margin: 5px;
outline: invert;
&:link {
transition : 0.5s;
text-decoration: none;
}
&:hover {
color: aquamarine;
}
&:active {
color: aqua;
position: relative;
top: 2px;
}
`
function App() {
return (
<AppDiv>
<BrowserRouter>
<BlackNav>
<NavStyle className={({isActive}) => (isActive? "active" : "")} to='/'>Home</NavStyle>
</BlackNav>
</BrowserRouter>
</AppDiv>
)
}
export default App;
원인을 파악해보니 NavLink
를 스타일링 하여 사용했기 때문이다.
아래 코드는 react-route-dom 라이브러리에 NavLink의 리턴 코드이다.
createElement
함수 마지막 인자로 children을 전달하는데 원래라면 isActive 값을 넘겨주게 되어있다.
const NavLink = /*#__PURE__*/forwardRef(function NavLinkWithRef(_ref5, ref) {
.
.
.
return /*#__PURE__*/createElement(Link, _extends({}, rest, {
"aria-current": ariaCurrent,
className: className,
ref: ref,
style: style,
to: to
}), typeof children === "function" ? children({
isActive
}) : children);
}
하지만, styled-components로 만든 스타일 코드는 children 객체로 다른 값(title)을 넘겨주는것 같다.
styled-components 라이브러리의 코드는 보기 어렵게 난독화 되어있는지 원래 그런 코드인지 모르겠다..
그래서 여러가지 방법들을 써보았다.
attrs()
로 props를 넘겨받아 보아도 undefined<NavStyle className={({isActive}) => (isActive? "active" : "")} to='/'>Home</NavStyle>
const NavStyle = styled(NavLink).attrs(props => ({
props: console.log(props),
}))`
.
.
.
function App() {
return (
<NavStyle activeClassName="active" to='/'>Home</NavStyle>
)
}
const NavStyle = styled(NavLink).attrs({
activeClassName
})`
https://yumyumlog.tistory.com/247
위 블로그를 보고 힌트를 받아서 문제를 해결할 수 있었다.
먼저, 아래 코드는 styled-components 라이브러리 사용법을 익히고 처음 만들었던 버튼 스타일이다.
/* components/styled.js */
import styled from "styled-components";
const BlueButton = styled.button`
background-color: #eee;
border: none;
outline: none;
&:hover {
color: blue;
outline: auto;
outline-color: blue;
}
&:active {
color: blue;
outline: auto;
outline-color: blue;
position: relative;
top: 2px;
}
`;
export {
BlueButton,
}
여기에 보면 버튼위 마우스를 올리거나 누를때의 스타일을 &:
로 지정을 한다.
그래서 NavLink에서도 같은 방법을 썼는데 active만 동작을 하지 않아서 문제가 되었다.
&:active { &.active {
color: aqua; color: aqua;
position: relative; => position: relative;
top: 2px; top: 2px;
} }
/* 변경 전 App.js */
import './App.css';
import { BrowserRouter, Routes, Route, NavLink } from 'react-router-dom';
import Home from './Pages/Home'
import About from './Pages/About'
import Contact from './Pages/Contact'
import Navigation from './Pages/Navigation'
function App() {
return (
<div className="App">
<BrowserRouter>
<nav className='black-nav'>
<div className='logoName'>Jaeminst Shop</div>
<NavLink className={({isActive}) => "nav-link" + (isActive? "a" : "")} to='/'>Home</NavLink>
<NavLink className={({isActive}) => "nav-link" + (isActive? "a" : "")} to='/about'>About</NavLink>
<NavLink className={({isActive}) => "nav-link" + (isActive? "a" : "")} to='/contact'>Contact</NavLink>
<NavLink className={({isActive}) => "nav-link" + (isActive? "a" : "")} to='/Navigation'>Navigation</NavLink>
</nav>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/about' element={<About />} />
<Route path='/contact' element={<Contact text='props text'/>} />
<Route path='/Navigation' element={<Navigation text='props text'/>} />
<Route path='/Navigation/:id' element={<Navigation text='props text'/>} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
/* 변경 후 App.js */
import styled from "styled-components";
import { BrowserRouter, Routes, Route, NavLink } from 'react-router-dom';
import Home from './Pages/Home'
import Detail from './Pages/Detail'
import About from './Pages/About'
import Contact from './Pages/Contact'
import Navigation from './Pages/Navigation'
const AppDiv = styled.div`
text-align: center;
`
const BlackNav = styled.div`
background: black;
width: 100%;
display: flex;
color: white;
padding: 20px;
font-weight: 500;
font-size: 20px;
box-sizing: border-box;
`
const LogoName = styled.div`
font-size: 30px;
width: 300px;
margin: 15px;
`
const NavStyle = styled(NavLink)`
color: white;
padding: 20px;
font-size: 20px;
font-weight: 400;
margin: 5px;
outline: invert;
&:link {
transition : 0.5s;
text-decoration: none;
}
&:hover {
color: aquamarine;
}
&.active {
color: aqua;
position: relative;
top: 2px;
}
`
function App() {
return (
<AppDiv>
<BrowserRouter>
<BlackNav>
<LogoName>Jaeminst Shop</LogoName>
<NavStyle to='/'>Home</NavStyle>
<NavStyle to='/about'>About</NavStyle>
<NavStyle to='/contact'>Contact</NavStyle>
<NavStyle to='/navigation'>Navigation</NavStyle>
</BlackNav>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/detail/:id' element={<Detail />} />
<Route path='/about' element={<About />} />
<Route path='/contact' element={<Contact text='props text'/>} />
<Route path='/navigation' element={<Navigation text='props text'/>} />
<Route path='/navigation/:id' element={<Navigation text='props text'/>} />
</Routes>
</BrowserRouter>
</AppDiv>
);
}
export default App;