// src/App.js
import React from "react";
// styled-components에서 styled 라는 키워드를 import 합니다.
import styled from "styled-components";
// styled키워드를 사용해서 styled-components 방식대로 컴포넌트를 만듭니다.
const StBox = styled.div`
// 그리고 이 안에 스타일 코드를 작성합니다. 스타일 코드는 우리가 알고 있는 css와 동일합니다.
width: 100px;
height: 100px;
border: 1px solid red;
margin: 20px;
`;
const App = () => {
// 그리고 우리가 만든 styled-components를 JSX에서 html 태그를 사용하듯이 사용합니다.
return <StBox>박스</StBox>;
};
export default App;
----------------------------------------------------------------------------------
//조건부 스타일링 예시
// src/App.js
import React from "react";
import styled from "styled-components";
// 1. styled-components를 만들었습니다.
const StBox = styled.div`
width: 100px;
height: 100px;
border: 1px solid ${(props) => props.borderColor}; // 4.부모 컴포넌트에서 보낸 props를 받아 사용합니다.
margin: 20px;
`;
const App = () => {
return (
<div>
{/* 2. 그리고 위에서 만든 styled-components를 사용했습니다. */}
{/* 3. 그리고 props를 통해 borderColor라는 값을 전달했습니다. */}
<StBox borderColor="red">빨간 박스</StBox>
<StBox borderColor="green">초록 박스</StBox>
<StBox borderColor="blue">파랑 박스</StBox>
</div>
);
};
export default App;
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
// 예시용 html
render() {
return (
<div className="Login"> // 최상의 Element의 이름은 컴포넌트의 이름과 통일시키는 것이 유지 보수할 때 좋다.
<div className="login-form"> // 부모
<img src={img} alt="Logo" /> // 자식
<input // 자식
className="userId"
type="text"
placeholder="전화번호, 사용자 이름 또는 이메일"
onChange={this.idInputCheck}
/>
<input // 자식
className="userPw"
type="password"
placeholder="비밀번호"
onChange={this.pwInputCheck}
/>
<button // 자식
className="loginBtn"
type="button"
style={{ backgroundColor: this.state.btnColor }}
onClick={this.btnClick}
>
로그인
</button>
</div>
</div>
);
}
/* css nesting 예시 */
/* 최상위 Element */
.Login {
box-sizing: border-box;
background-color: rgba(var(--b3f, 250, 250, 250), 1);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
/* 부모 */
.login-form {
margin: 0 auto;
display: flex;
flex-direction: column;
background-color: white;
border: 1px solid rgba(var(--b6a, 219, 219, 219), 1);
width: 350px;
height: 300px;
padding: 0px 25px;
/* 자식 1 */
img {
padding: 30px 45px 45px 45px;
margin-bottom: 0px;
}
/* 자식 2 */
.userId {
background-color: rgba(var(--b3f, 250, 250, 250), 1);
margin-bottom: 10px;
padding: 8px;
border-radius: 4px;
border: 1px solid #cdced0;
}
/* 자식 3 */
.userPw {
background-color: rgba(var(--b3f, 250, 250, 250), 1);
padding: 8px;
border-radius: 4px;
margin-bottom: 15px;
border: 1px solid #cdced0;
}
/* 자식 4 */
.loginBtn {
color: white;
font-weight: bold;
padding: 3px 0;
border: 1px solid #b2dffc;
border-radius: 4px;
}
}
}
// GlobalStyle.jsx
import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
*, *::before, *::after {
box-sizing: border-box;
}
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
body {
font-family: "Helvetica", "Arial", sans-serif;
line-height: 1.5;
}
h2, p {
margin: 0;
}
h2 {
font-size: 1.5rem;
}
p {
font-size: 1rem;
}
`;
export default GlobalStyle;
import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";
function App() {
return (
<>
<GlobalStyle />
<BlogPost title="Styled Components 전역 스타일링">
이번 포스팅에서는 Styled Components로 전역 스타일을 정의하는 방법에
대해서 알아보겠습니다.
</BlogPost>
</>
);
}
export default App;
useEffect(() => {
// 실행하고 싶은 함수
},[의존성 배열]);
의존성 배열은 useEffect가 바라보고 있는 곳으로, 해당하는 의존성배열의 상태가 변경되면 useEffect가 실행 된다.
의존성 배열란을 제거하면 해당 컴포넌트가 리렌더링(update) 될때마다 실행된다.
useEffect(() => {
// 실행하고 싶은 함수
},);
의존성 배열에 빈값을 넣으면 처음 리렌더링(mount) 될때에만 1번 실행 된다.
useEffect(() => {
// 실행하고 싶은 함수
},[]);
의존성 배열에 값을 넣으면 해당하는 값의 상태가 변경될때마다(update) 실행 된다.
useEffect(() => {
// 실행하고 싶은 함수
},[value]);
// src/App.js
import React, { useEffect } from "react";
const App = () => {
useEffect(()=>{
// 화면에 컴포넌트가 나타났을(mount) 때 실행하고자 하는 함수를 넣어주세요.
return ()=>{
// 화면에서 컴포넌트가 사라졌을(unmount) 때 실행하고자 하는 함수를 넣어주세요.
}
}, [])
return <div>hello react!</div>
};
export default App;
중앙 state 관리소를 사용할 수 있게 도와주는 패키지(라이브러리)이다.
설치 : 터미널 창에 "yarn add redux react-redux"" 입력
폴더 구조
- src 폴더 안에 redux 폴더 생성
- redus : 리덕스와 관련된 코드를 모아놓은 폴더
- redux 폴더 안에 config, modules 생성
- config : 리덕스 설정과 관련된 파일을 모아 놓은 폴더
- modules : 우리가 만들 State들의 그룹, 예를 들어 "todolist"를 만들때 필요한 state들이 모두 모여있을 todo.js를 생성하게 될텐데, 이 todo.js 파일이 하나의 모듈이 된다.
- config 폴더 안에 configStore.js 파일 생성
- configStore : 중앙 state 관리소인 Store를 만드는 설정 코드가 있는 파일
redux 사용 순서
import { createStore } from "redux";
import { combineReducers } from "redux";
const rootReducer = combineReducers({});
const store = createStore(rootReducer);
export default store;
// 원래부터 있던 코드
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// 우리가 추가할 코드
import store from "./redux/config/configStore";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
//App을 Provider로 감싸주고, configStore에서 export default 한 store를 넣어줍니다.
<Provider store={store}>
<App />
</Provider>
);
reportWebVitals();
버튼이든 뭐든 구현
구현한 것의 이벤트 핸들러에 dispatch({액션객체}) 넣어주기
리듀서로 로직 구현
초기값 설정
카운터 모듈을 스토어에 연결
유즈 셀럭터로 app.js에서 불러오기
// src/shard/Router.js
import React from "react";
// 1. react-router-dom을 사용하기 위해서 아래 API들을 import 합니다.
import { BrowserRouter, Route, Routes } from "react-router-dom";
// 2. Router 라는 함수를 만들고 아래와 같이 작성합니다.
const Router = () => {
return (
<BrowserRouter>
<Routes>
</Routes>
</BrowserRouter>
);
};
export default Router;
// src/shard/Router.js
// 4개의 페이지 컴포넌트마다 Route를 설정
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Home from "../pages/Home";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Works from "../pages/Works";
const Router = () => {
return (
<BrowserRouter>
<Routes>
{/*
Routes안에 이렇게 작성합니다.
Route에는 react-router-dom에서 지원하는 props들이 있습니다.
paht는 우리가 흔히 말하는 사용하고싶은 "주소"를 넣어주면 됩니다.
element는 해당 주소로 이동했을 때 보여주고자 하는 컴포넌트를 넣어줍니다.
*/}
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="works" element={<Works />} />
</Routes>
</BrowserRouter>
);
};
export default Router;
// App.js에 Route.js import
import React from "react";
import Router from "./shared/Router";
function App() {
return <Router />;
}
export default App;
// src/App.js
const App = () => {
const navigate = useNavigate();
return (
<button
onClick={() => {
navigate("/works");
}}
>
works로 이동
</button>
);
}
export default App;
// src/App.js
import React from "react";
import { Link } from "react-router-dom";
const App = () => {
return <Link to="/contact">Home</Link>;
};
export default App;