본문 바로가기

[내일배움캠프] 프로덕트 디자인 8기/TIL(Today I Learned)

[TIL] 25.01.06(월)

React 숙련 1주차

 

 

1-1

Styled-components 1

import "./App.css";
import styled from "styled-components";

const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid red;
  margin: 20px;
`;

const StP = styled.p`
  color: blue;
`

function App() {
  return (
    <>
    <StBox>
      <StP>스타일이 적용된 p태그</StP>
    </StBox>
    </>
  );
}

export default App;
import "./App.css";
import styled from "styled-components";

const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${props => props.borderColor};
  margin: 20px;
`;

function App() {
  return (
    <>
    <StBox borderColor="red">빨간 박스</StBox>
    <StBox borderColor="green">초록 박스</StBox>
    <StBox borderColor="blue">파랑 박스</StBox>
    </>
  );
}

export default App;
import "./App.css";
import styled from "styled-components";

const StBox = styled.div`
  width: 100px;
  height: 100px;
  border: 1px solid ${props => props.borderColor};
  margin: 20px;
`;

const boxList = ["red", "green", "blue"];

const getBoxName = (color) => {
  switch (color) {
    case "red":
    return "빨간 박스";
    case "green":
    return "초록 박스";
    case "blue":
    return "파랑 박스";
    default:
      return "검정 박스";
  }
};

function App() {
  return (
    <>
    {
    boxList.map((boxColor) => {
      return <StBox
      key={boxColor} borderColor={boxColor}>
        {getBoxName(boxColor)}
        </StBox>;
    })}
    </>
  );
}

export default App;

 

 

 

1-2

Styled-components 2, resrt css

import styled from "styled-components";

function TestPage(props) {
  return (
    <Wrapper>
      <Title>{props.title}</Title>
      <Contents>{props.contents}</Contents>
    </Wrapper>
  );
}

const Title = styled.h1`
  font-family: "Helvetica", "Arial", sans-serif;
  line-height: 1.5;
  font-size: 1.5rem;
  margin: 0;
  margin-bottom: 8px;
`;

const Contents = styled.p`
  margin: 0;
  font-family: "Helvetica", "Arial", sans-serif;
  line-height: 1.5;
  font-size: 1rem;
`;

const Wrapper = styled.div`
  border: 1px solid black;
  border-radius: 8px;
  padding: 20px;
  margin: 16px auto;
  max-width: 400px;
`;

export default TestPage;
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    font-family: "Helvetica", "Arial", sans-serif;
    line-height: 1.5;
  }
`;

export default GlobalStyle;
function BlogPost({ title, contents }) {
  return (
    <>
      <p>{title}</p>
      <p>{contents}</p>
    </>
  );
}

export default App;
import GlobalStyle from "./GlobalStyle";
import BlogPost from "./BlogPost";

function App() {
	const title = '전역 스타일링 제목입니다.';
	const contents = '전역 스타일링 내용입니다.';
  return (
    <>
      <GlobalStyle />
      <BlogPost title={title} contents={contents} />
    </>
  );
}

export default App;

 

CSS 초기화 코드

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;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./reset.css" />
  </head>
  <body>
    <span>Default Style을 테스트 해 봅니다.</span>
    <h1>이건 h1 태그에요</h1>
    <p>이건 p 태그에요</p>
  </body>
</html>

 

 

 

1-3

useState

import { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  const handleCountPlus = () => {
    setCount((현재값)=>{
      return 현재값 +1;
    });

    // setCount(count + 1);
  };
  
  return (
  <div>
    {count}<br />
    <button onClick={handleCountPlus}>
      증가
      </button>
      </div>
  );
};

export default App;
import { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);
  
  return (
  <div>
    {count}<br />
    <button onClick={()=>{
      // setCount(count + 1);
      // setCount(count + 1);
      // setCount(count + 1);
      setCount((prev)=>prev + 1);
      setCount((prev)=>prev + 1);
      setCount((prev)=>prev + 1);
    }}
    >
      증가
      </button>
      </div>
  );
};

export default App;
import React from 'react'

const Child = ({setCount}) => {
    return (
        <div>
            <h3>여기는 자식 컴포넌트입니다.</h3>
            <button
                onClick={() => {
                    setCount((prev) => prev + 1);
                }}
                >
                증가!
                </button>
        </div>
    );
};

export default Child;
import { useState } from "react";
import Child from "./assets/components/Child";

const App = () => {
  const [count, setCount] = useState(0);
  
  return (
  <div>
   <h1>여기는 부모컴포넌트입니다.</h1>
   <span>현재 카운트 : {count}</span>
   <Child setCount={setCount}/>
      </div>
  );
};

export default App;

 

 

 

1-4

useEffect

import react, { useEffect, useState } from "react";

const App = () => {
  const [value, setValue] = useState("");
  const [coutn, setCount] = useState(0);

  // 의존성 배열: 이 배열에 값을 넣으면 그 값이 바뀔 때만
  // useEffect를 실행할게!
useEffect(() => {
  console.log("hello useEffect");
}, [coutn]); 

return (
  <div>
    <h1>useEffect</h1>
    <input
    type="text"
    value={value}
    onChange={(e) => {
      setValue(e.target.value);
    }}
    />
    {coutn}
    <button
    onClick={() => {
      setCount(coutn + 1);
    }}
    >증가
    </button>
  </div>
);
};

export default App;

 

컴포넌트 라이프사이클

리액트 컴포넌트도 태어나고, 살아나고, 죽는 생애주기가 존재함. 클래스형 컴포넌트를 주로 사용했을 이전 버전에서는 이 생애주기와 관련된 여러 메서드가 존재했지만, 현재처럼 함수형 컴포넌트를 사용할때는 useEffect를 주로 사용하여 핸들링함.

 

 

 

1-6

react router dom 1 - 소개, 세팅, hooks

import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import About from "../pages/About";
import Contact from "../pages/Contact";
import Home from '../pages/Home'
import Works from "../pages/Works";

const Router = () => {
    return (
        <BrowserRouter>
        <Routes>
            {/* Route */}
            <Route path="/" element={<Home />} />
            <Route path="/about" element={<About />} />
            <Route path="contact" element={<Contact />} />
            <Route path="works" element={<Works />} />
        </Routes>
        </BrowserRouter>
    )
}

export default Router

 

import React from "react";

const About = () => {
    return <div>About</div>;
};

export default About;
import "./App.css";
import Router from "./shared/Router";

function App() {
  return <Router />;
}
  

export default App;
import React from "react";
import {useNavigate} from "react-router-dom";

const Home = () => {
    const navigate = useNavigate();

    return (
    <div>
        <h1>Home 컴포넌트입니다.</h1>
        <button
        onClick={() => {
            navigate("/works");
        }}
        >
            works로 이동
        </button>
    </div>
    );
};

export default Home;
import React from "react";
import {useNavigate} from "react-router-dom";

const Works = () => {
    const navigate = useNavigate();

    return (
    <div>
        <h1>Works 페이지입니다.</h1>
        <button
        onClick={() => {
            navigate("/");
        }}
        >
            home으로 이동
        </button>
    </div>
    );
};

export default Works;
import React from "react";
import {useLocation, useNavigate} from "react-router-dom";

const Works = () => {
    const navigate = useNavigate();
    const location = useLocation();

    console.log('location', location);

    return (
    <div>
        <h1>Works 페이지입니다.</h1>
        <div>현재 페이지: {location.pathname.slice(1)}</div>
        <button
        onClick={() => {
            navigate("/");
        }}
        >
            home으로 이동
        </button>
    </div>
    );
};

export default Works;
import React from "react";
import {Link, useLocation, useNavigate} from "react-router-dom";

const Works = () => {
    const navigate = useNavigate();
    const location = useLocation();

    console.log('location', location);

    return (
    <div>
        <h1>Works 페이지입니다.</h1>
        <div>현재 페이지: {location.pathname.slice(1)}</div>
        {/* <button
        onClick={() => {
            navigate("/");
        }}
        >
            home으로 이동
        </button> */}
        <Link to="/contatc">contact 페이지로 이동하기</Link>
    </div>
    );
};

export default Works;

 

 

 

1-17

react router dom 2 - children

어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올지 미리 예상할 수 없는 경우가 있음. 범용적인 ‘박스’ 역할을 하는 Sidebar 혹은 Dialog와 같은 컴포넌트에서 특히 자주 볼 수 있음.

여기서 말하는 범용적인 “박스” 역할을 하는 컴포넌트란 크게 봤을 때 Layout 역할을 하는 컴포넌트라고 생각해볼 수 있음.

children props를 찾아보면 composition이라는 말을 많이 볼 수 있는데, composition은 합성이라는 의미가 있음.

(아래 예시는 children props를 가지고 페이지 레이아웃을 만들며 개별적으로 존재하는 Header, Footer, Page를 합성하여 개발자가 의도하는 UI를 만들어주는 Layout 컴포넌트 코드)

 

src/shared/Layout.js

// src/shared/Layout.js

import React from 'react';

const HeaderStyles = {
  width: '100%',
  background: 'black',
  height: '50px',
  display: 'flex',
  alignItems: 'center',
  paddingLeft: '20px',
  color: 'white',
  fontWeight: '600',
};
const FooterStyles = {
  width: '100%',
  height: '50px',
  display: 'flex',
  background: 'black',
  color: 'white',
  alignItems: 'center',
  justifyContent: 'center',
  fontSize: '12px',
};

const layoutStyles = {
  display: 'flex',
	flexDirection: 'column',
  justifyContent: 'center',
  alignItems: 'center',
  minHeight: '90vh',
}

function Header() {
  return (
    <div style={{ ...HeaderStyles }}>
      <span>Sparta Coding Club - Let's learn React</span>
    </div>
  );
}

function Footer() {
  return (
    <div style={{ ...FooterStyles }}>
      <span>copyright @SCC</span>
    </div>
  );
}


function Layout({ children }) {
  return (
    <div>
      <Header />
      <div style={{...layoutStyles}}>
        {children}
      </div>
      <Footer />
    </div>
  );
}

export default Layout;

 

 

src/shared/Router.js

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';
import Layout from './Layout';

const Router = () => {
  return (
    <BrowserRouter>
      <Layout>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="contact" element={<Contact />} />
          <Route path="works" element={<Works />} />
        </Routes>
      </Layout>
    </BrowserRouter>
  );
};

export default Router;

'[내일배움캠프] 프로덕트 디자인 8기 > TIL(Today I Learned)' 카테고리의 다른 글

[TIL] 25.01.08(수)  (0) 2025.01.08
[TIL] 25.01.07(화)  (0) 2025.01.07
[TIL] 25.01.02(목)  (0) 2025.01.01
[TIL] 24.12.31(화)  (1) 2024.12.31
[TIL] 24.12.30(월)  (0) 2024.12.30