-
Notifications
You must be signed in to change notification settings - Fork 7
라우팅 초기작업 #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
라우팅 초기작업 #39
Changes from all commits
0a5a87d
6cad20d
272f464
0e7e48d
fdf448a
cb95a0d
dba44df
6875e56
756cf77
81b4fa3
73c0cf7
dcc26f8
9900c46
b0401c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,35 @@ | ||
| import logo from 'assets/logo.svg'; | ||
| import './App.css'; | ||
| import { useLocation, Routes, Route, Navigate } from 'react-router-dom'; | ||
| import Layout from 'pages/Layout/Layout'; | ||
| import Home from 'pages/Home/Home'; | ||
| import Search from 'pages/Search/Search'; | ||
| import MyRecipes from 'pages/MyRecipes/MyRecipes'; | ||
| import Modal from 'pages/Modal/Modal'; | ||
| import PageNotFound from 'pages/PageNotFound/PageNotFound'; | ||
|
|
||
| function App() { | ||
| const location = useLocation(); | ||
| const state = location.state as { backgroundLocation?: Location }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React Router DOM에서 원래 이런식으로 사용하는 지 궁금합니다!(단언문 형태로)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 제가 공식문서의 예제를 보고 참고했습니다. |
||
| const backgroundLocation = state?.backgroundLocation; | ||
|
|
||
| return ( | ||
| <div className="App"> | ||
| <header className="App-header"> | ||
| <img src={logo} className="App-logo" alt="logo" /> | ||
| <p> | ||
| Edit <code>src/App.tsx</code> and save to reload. | ||
| </p> | ||
| <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer"> | ||
| Learn React | ||
| </a> | ||
| </header> | ||
| </div> | ||
| <> | ||
| <Routes location={backgroundLocation || location}> | ||
| <Route path="/" element={<Layout />}> | ||
| <Route index element={<Home />} /> | ||
| <Route path="search/:keyword" element={<Search />} /> | ||
| <Route path="my-recipes" element={<MyRecipes />} /> | ||
| <Route path="/detail/:id" element={<Modal />} /> | ||
| <Route path="page-not-found" element={<PageNotFound />} /> | ||
| <Route path="*" element={<Navigate to="page-not-found" replace />} /> | ||
| </Route> | ||
| </Routes> | ||
| {backgroundLocation && ( | ||
| <Routes> | ||
| <Route path="/detail/:id" element={<Modal />} /> | ||
| </Routes> | ||
| )} | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
| import Label from './Label'; | ||
|
|
||
| export default { | ||
| title: 'Label', | ||
| component: Label, | ||
| args: { | ||
| type: 'time', | ||
| value: 0, | ||
| }, | ||
| } as ComponentMeta<typeof Label>; | ||
| const Template: ComponentStory<typeof Label> = (args) => <Label {...args} />; | ||
|
|
||
| export const DefaultTimeLabel = Template.bind({}); | ||
|
|
||
| export const TimeLabel = Template.bind({}); | ||
|
|
||
| TimeLabel.args = { | ||
| value: 255, | ||
| }; | ||
|
|
||
| export const DefaultBookMarkLabel = Template.bind({}); | ||
|
|
||
| DefaultBookMarkLabel.args = { | ||
| type: 'bookmark', | ||
| value: 0, | ||
| }; | ||
|
|
||
| export const BookMarkLabel = Template.bind({}); | ||
|
|
||
| BookMarkLabel.args = { | ||
| type: 'bookmark', | ||
| value: 10, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import styled from 'styled-components'; | ||
|
|
||
| export const StyledLabel = styled.p` | ||
| color: #cbcbcb; | ||
| font-size: rem(24px); | ||
| display: block; | ||
| padding: rem(10px) 0; | ||
| `; | ||
|
|
||
| export const StyledStrong = styled.strong` | ||
| font-weight: bolder; | ||
| `; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| import { BsBookmarkHeartFill } from 'react-icons/bs'; | ||
| import { RiTimerFill } from 'react-icons/ri'; | ||
| import { LabelProps } from './Label.types'; | ||
| import { StyledLabel, StyledStrong } from './Label.styled'; | ||
|
|
||
| export default function Label({ type, value }: LabelProps): JSX.Element { | ||
| const iconStyle = { | ||
| marginRight: '20px', | ||
| fontSize: '26px', | ||
| verticalAlign: 'bottom', | ||
| }; | ||
|
|
||
| const renderByType = (type: string) => { | ||
| switch (type) { | ||
| case 'time': | ||
| return ( | ||
| <> | ||
| <RiTimerFill style={iconStyle} /> | ||
| Ready in <StyledStrong>{value} minutes </StyledStrong> | ||
| </> | ||
| ); | ||
| case 'bookmark': | ||
| return ( | ||
| <> | ||
| <BsBookmarkHeartFill style={iconStyle} /> | ||
| <StyledStrong>{value}</StyledStrong> saved | ||
| </> | ||
| ); | ||
| default: | ||
| return null; | ||
| } | ||
| }; | ||
| return <StyledLabel>{renderByType(type)}</StyledLabel>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| export interface LabelProps { | ||
| type: string; | ||
| value: number; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| export { default as App } from './App/App'; | ||
| export { default as Label } from './Label/Label'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,20 @@ | ||
| import { StrictMode } from 'react'; | ||
| import { render } from 'react-dom'; | ||
| import { BrowserRouter } from 'react-router-dom'; | ||
| import { ThemeProvider } from 'styled-components'; | ||
| import { GlobalStyle } from 'styles/GlobalStyle'; | ||
| import { defaultTheme } from 'theme/theme'; | ||
| import { App } from './components'; | ||
| // import './reportWebVitals'; | ||
| import './styles/global.css'; | ||
|
|
||
| render( | ||
| <StrictMode> | ||
| <App /> | ||
| <ThemeProvider theme={defaultTheme}> | ||
| <GlobalStyle /> | ||
| <BrowserRouter> | ||
| <App /> | ||
| </BrowserRouter> | ||
| </ThemeProvider> | ||
| </StrictMode>, | ||
| document.getElementById('root'), | ||
| ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function Home() { | ||
| return <div>Home</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { Outlet } from 'react-router-dom'; | ||
|
|
||
| export default function Layout() { | ||
| return ( | ||
| <main> | ||
| <Outlet /> | ||
| </main> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function Modal() { | ||
| return <div>Modal</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function MyRecipes() { | ||
| return <div>MyRecipes</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function PageNotFound() { | ||
| return <div>PageNotFound</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export default function Search() { | ||
| return <div>Search</div>; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import { createGlobalStyle } from 'styled-components'; | ||
| import { normalize } from 'styled-normalize'; | ||
|
|
||
| export const GlobalStyle = createGlobalStyle` | ||
| ${normalize} | ||
|
|
||
| /* 시맨틱 태그 iE 맞춤 */ | ||
| header, | ||
| footer, | ||
| main, | ||
| section, | ||
| article, | ||
| aside, | ||
| nav, | ||
| figure, | ||
| figcaption { | ||
| display: block; | ||
| } | ||
|
|
||
| /* 기본 스타일 */ | ||
| /* 기본 박스 사이징 설정 */ | ||
|
|
||
| body, | ||
| body::before, | ||
| body::after, | ||
| body *, | ||
| body *::before, | ||
| body *::after { | ||
| box-sizing: border-box; | ||
| } | ||
|
|
||
| /* 본문 기본 폰트, 글자 크기, 굵기, 배경 색상 지정 */ | ||
| /* @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600&display=swap'); */ | ||
|
|
||
| @font-face { | ||
| font-family: 'Montserrat'; | ||
| font-weight: normal; | ||
| font-style: normal; | ||
| src: url('./fonts/Montserrat-Regular.woff2') format('woff2'), | ||
| url('.assets/fonts/Montserrat-Bold.woff2') format('woff2'); | ||
| font-display: block; | ||
| unicode-range: U+000-5FF; | ||
| } | ||
|
|
||
| body { | ||
| font-family: 'Montserrat', 'Roboto', sans-serif; | ||
| font-size: inherit; | ||
| position: relative; | ||
| } | ||
|
|
||
| /* 제목 글자 크기 및 굵기 재지정 */ | ||
| h1, | ||
| h2, | ||
| h3, | ||
| h4, | ||
| h5, | ||
| h6 { | ||
| font-size: 100%; | ||
| font-weight: inherit; | ||
| margin: 0; | ||
| } | ||
|
|
||
| /* 목록 안쪽 여백 및 불릿 제거 */ | ||
| ul, | ||
| ol { | ||
| padding-left: 0; | ||
| list-style: none; | ||
| } | ||
|
|
||
| /* 이미지에 발생하는 갭 제거 */ | ||
| img { | ||
| vertical-align: middle; | ||
| } | ||
|
|
||
| /* 링크 요소의 밑줄 및 글자 색상 재 정의 */ | ||
| a { | ||
| color: inherit; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| /* 주소 및 강조 요소 스타일 재 정의 */ | ||
| address, | ||
| em { | ||
| font-style: normal; | ||
| } | ||
|
|
||
| /* fieldset 요소의 테두리 및 여백 제거 */ | ||
| fieldset { | ||
| border: 0; | ||
| padding: 0; | ||
| margin: 0; | ||
| } | ||
|
|
||
| /* 버튼 마우스 스타일 설정 */ | ||
| button { | ||
| cursor: pointer; | ||
| color: inherit; | ||
| font-size: inherit; | ||
| } | ||
|
|
||
| /* form 요소 스타일 설정 */ | ||
| input::-ms-clear, | ||
| input::-ms-reveal { | ||
| display: none; | ||
| } | ||
| input::-webkit-search-decoration, | ||
| input::-webkit-search-cancel-button, | ||
| input::-webkit-search-results-button, | ||
| input::-webkit-search-results-decoration { | ||
| display: none; | ||
| } | ||
|
|
||
| input, | ||
| button, | ||
| textarea { | ||
| appearance: none; | ||
| -webkit-appearance: none; | ||
| } | ||
|
|
||
|
|
||
| /* figure 기본 스타일 제거 */ | ||
| figure { | ||
| margin: 0; | ||
| } | ||
| `; |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useLocation으로 반환하는 값이 어떤것이죠?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useLocation은 location 객체를 반환하는데 이런 프로퍼티를 가지고있습니다.
location: {
pathname: string;
search: string;
hash: string;
state: unknown;
key: string;
};
참고링크: https://github.com/remix-run/history/blob/main/docs/api-reference.md#location