노마드코더 인스타그램 클론코딩 바로가기 https://nomadcoders.co/instaclone
npx create-react-app instaclone-web
npm i styled-components react-hook-form react-router-dom @apollo/client graphql react-helmet-async
styled-components
React Hook Form
React Router
Apollo Client,graphql : graphql에 접근하기 위해 필요
React Helmet : web의 title을 동적으로 구현 가능하게 해주는 라이브러리
React-fontawesome : https://fontawesome.com/how-to-use/on-the-web/using-with/react 필요한 부분을 추가
프로젝트의 SETUP이라는 것은 단지 파일을 생성하고 설치하는 것에 그치는 것이 아니고 App의 기초를 다지는 것을 뜻한다.
즉 무엇이 필요하고 무엇을 해야하고 왜 해야하는지를 알고 있는 것이 중요하다.
Switch를 사용하는 이유 한번에 하나의 router만 render하고 싶기 때문에
쉽게 설명하자면 Switch Case 문과 같은 역할을 한다고 생각하면 된다.
Case의 역할을 Route가 하게 되는 것이고 각 Route의 path와 매칭을 해보고 매칭되는 단 하나만 Render된다.
React Router의 성질 때문에 pattern matching을 하는데 , 이 때문에 / 경로를 요청해도 /potato, /banana 와 같은 /이 포함된 모든 Router가 Render될 것이다. 이 때문에 Switch를 사용해 하나만 랜더링 되게 해주는 것이고 Switch를 적어주게 되면 /,/potato,/banana모든 url에서 path가 /인 Router만 랜더되는 것을 볼 수 있다. 이는 하나만 랜더링 시키는데 처음 패턴매칭이되는 /가 랜더링 되는 것이고
이와 같은 문제를 해결하기 위해 root path인 / Route에 exact 라는 속성을 추가해준다.
추가해주게 되면 정확하게 path가 매칭이 되는 Router만 Render 되는 것을 볼 수 잇다.
HashRouter과의 차이점은 단지 url에 /#/ 가 붙냐 안붙냐의 차이이다. 일반적으로 우리가 보는 웹사이트의 URL은 BrowserRouter형태로 되어져 있다. 그러나 프로젝트를 deploy할때 BrowserRouter의 경우는 몇가지의 Step을 더 밟아야 한다고 한다. 이는 나중에 알아볼 것이다.
먼저 로그인이 됬을때의 Home과 로그인이 되지 않았을때의 Home(/)일때의 화면은 차이가 있다. 이 화면들은 Component로 구현한다.
그리고 Router에 없는 url을 입력했을때의 방법은 2가지가 있따.
nico 쌤은 1번 path가 없는 Route를 작성해줘 404 컴포넌트를 랜더링 해주는 것을 추천
가장 최상위 컴포넌트에서 isLoggedIn이란 state가 있다.
이를 하위 모든 컴포넌트들로부터 Control이 가능해야한다.
이를 위해서는 props로 일일이 전달해주는 방법이 있지만 이 방법은 매우 비효율적이다.
현재 내가 아는 방법은 총 2가지가 있다.
1. Context API
2. REDUX
// apollo.js
import {makeVar} from "@apollo/client";
export const isLoggedInVar = makeVar(false);
import {useReactiveVar} from "@apollo/client";
import {isLoggedInVar} from "./apollo";
// App.js
const isLoggedIn = useReactiveVar(isLoggedInVar);
//Login.js
import { isLoggedInVar } from "../apollo";
const Login = () => {
return (
<div>
<h1>Login</h1>
<button onClick={() => isLoggedInVar(true)}>로그인</button>
</div>
);
};
export default Login;
Reactive Variables를 사용함으로써 하위 어떠한 컴포넌트에서도 isLoggedIn을 Control 할 수 있다.
- DarkMode를 구현하기 위해서는 styled-components의 ThemeProvider를 사용한다.
- ThemeProvider의 props로 theme를 전달해줄 것이기 때문에 Router의 상위 컴포넌트로 구현한다.
// App.js
const darkTheme = {
fontColor:"white",
bgColor:"black",
};
const lightTheme = {
fontColor:"black",
bgColor:"white",
};
<ThemeProvider theme={darkMode?darkTheme:lightTheme}>
<Router>
<Switch>
...
...
</Switch>
</Router>
</ThemeProvider>
// Login.js
const Container = styled.div`
background-color:${props=>props.theme.bgColor};
`
const Title = styled.h1`
color:${props=>props.theme.fontColor};
`
<Container>
<Title>Login</Title>
<button onClick={()=>darkModeVar(true)}>dark-mode on</button>
<button onClick={()=>darkModeVar(false)}>light-mode on</button>
</Container>
- styled-components의 ThemeProvider을 이용해 theme를 props로 하위 컴포넌트에 전달해준다.
- Reactive Variables을 이용해 darkModeVar을 생성해주고 이를 필요한 하위 컴포넌트에서 사용해줬다.
- darkMode의 Boolean값에 따라 서로다른 theme Obj가 전달되고 이를 이용해서 style한다.
styled-components을 이용한 CSS RESET 방법
1.yarn add styled-reset
2. createGlobalStyle을 사용
3. createGlobalStyle과 theme의 결합
4. createGlobalStyle과 styled-reset의 결합
// App.js
<ThemeProvider theme=...>
<GlobalStyles/>
<Router>
...
...
</ThemeProvider>
// styles.js
export const GlobalStyles = createGlobalStyle`
${reset}
body{
background-color:${props=>props.theme.bgColor};
color:${props=>props.theme.fontColor};
}
`