[멋사] 3주차 회고록

김아현·2026년 4월 7일

멋사 14기

목록 보기
3/6

이번주 과제는 1주차때 만든 자기소개 카드 리엑트에 그대로 재현하기 이다 일단 나는 vs코드에서 리엑트 연결하는 과정부터 써볼까한다

HTML 자기소개 카드 리엑트에 재현

리엑트 연결법

  1. vs코드에서 폴더를 연다
  2. npx-create-react-app 프로젝트명 입력해 설치
  3. 경로가 바꿔있는지 확인한 후 npm start 를 치고 시작
    경로 확인을 안하고 npm start 하면 오류 뜰 수 있음...ㅎ....

재현

1. App.js return 안에 html 코드 붙여넣기

scr 안에 App.js 에서 하면 됨
일단 원래 있던거 지우고 html 코드에서 body 파트를 가져옴

Jsx 에서는 return 안에 하나의 최상위 태그를 가지고 있어야 함
(가장 큰 태그가 하나여야 함)

그래서 나는 <> </> 로 감싸줌

왜냐
  • JSX는 HTML이 아니라 JavaScript로 변환된다
  • JavaScript의 return은 하나의 값만 반환 가능하다
  • 따라서 JSX도 하나의 최상위 요소로 감싸야 한다

그렇다고 한다 결론은

JSX는 결국 JavaScript 라서 return은 하나만 된다
→ 그래서 하나로 묶어야 한다

2. class 교체

html에서 <div class="title"> 같은 형식으로 쓴 이 친구들을 바꿔줘야 함

왜냐

class 라는 예약어가 존재하기 때문
'즉' 사용할 수 없다
그래서
-> <div className="title"> 이라는 형식으로 쓴다

class 를 대문자 N 이 들어간 className 으로 쓰면 된다

3. styled-components 로 꾸미기

가 과제 조건이므로 이 방식으로 만들어보자

우선
styled-components란
CSS를 JavaScript 안에서 작성할 수 있게 해주는 라이브러리이다.

👉 쉽게 말하면
'컴포넌트에 스타일을 같이 묶어서 관리하는 방식' 이라고 한다

일단 가장 위에 import styled from "styled-components"; 를 넣어 주고 const 컴포넌트 이름 (변수명) = styled.HTML 태그 형식으로 쓴다

이렇게보면 이해가 안되니까 예시를 보면

이런 식으로 쓰면 된다

4. 좋아요 버튼 만들기

좋아요 버튼은 상태 변화를 관리할 수 있는 useState
이용해 구현할 수 있다

useState를 사용하면 클릭 여부나 좋아요 개수와 같은 값을 저장하고,
변경될 때마다 화면을 자동으로 업데이트할 수 있다

useState 를 사용하기 위해서는 상단에 다음과 같이 import 해주어야 한다

import { useState } from "react"; 
// react에서 useState 기능 불러오기 

하고
const [데이터명, 데이터를 변경해주는 함수명] = useState(초기값); 를 입력해 컴포넌트에서 사용할 상태(state)를 생성한다

그리고 onClick 을 사용해서 클릭 시 좋아요가 1 증가하도록 설정해준다

<span onClick={()=> {좋아요변경(좋아요 + 1)}}> 🩶 </span>

button 대신 span을 사용한 이유는 좀 더 예쁘게 만들고 싶어서 ㅎ.. 기본 스타일 안 쓰려고 ㅎ...


이렇게 만들면 된다!!

최종 코드

import styled from "styled-components";
import { useState } from "react";

const Container = styled.article`
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    background-color: lightgray;
    padding: 30px; 
    border-radius: 20px;
    width: 600px;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
    display: flex;
    flex-direction: column;
    gap: 30px;
`;

const Profiles = styled.section`
    background-color: white;
    padding: 20px;
    border-radius: 15px;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
`;

const Role = styled.p`
    color: blue;
    font-weight: bold;
    margin: 5px 0;
`;

const Img = styled.img`
    width: 170px;
    height: 170px;
    object-fit: cover;
    border-radius: 10px;
    margin-bottom: 10px;
`;

const Details = styled.section`
    background-color: white;
    padding: 20px;
    border-radius: 15px;
    box-shadow: 0 10px 20px rgba(0,0,0,0.1);
`;
const Text = styled.p`
    margin: 5px 0;
`;
const Title = styled.h2`
    margin: 0 0 5px;
`;

const SubTitle = styled.h3`
    margin-top: 20px;
`;

const List = styled.ul`
    padding-left: 20px;
`;

const Item = styled.li`
    margin-bottom: 5px;
`;

const LinkText = styled.a` 
    color: blue;
    &:hover {
        text-decoration: underline;
    }
`;

function App() {

    let [좋아요, 좋아요변경] = useState(0);

    return (
    <> 
        <Container>
            <Profiles>
                <img src="p.jpg" width="200" height="200" />
                <span onClick ={()=>{좋아요변경(좋아요+1)}}>🩶</span>{좋아요}
                <div>
                    <Title>김아기사자</Title>
                    <Role>Frontend</Role>
                    <Text>열심히 배우는 프론트엔드입니다.</Text>
                </div>
            </Profiles>
            <Details>
                <Title>김아기사자</Title>
                <Role>Frontend</Role>
                <Text>멋쟁이사자처럼</Text>

                <SubTitle>자기소개</SubTitle>
                <Text>인천대 아기사자 14기 프론트엔드 개발자입니다. 저는 F1이랑 웹툰보는거 좋아합니다. 친해지면 말도 많아져요!</Text>

                <SubTitle>연락처</SubTitle>
                <List>
                    <Item>이메일: kah@gmail.com</Item>
                    <Item>전화: 010-0000-0000</Item>
                    <Item>웹사이트:<LinkText href="https://velog.io/@_zn_/posts" target="_blank">https://velog.io/@_zn_/posts</LinkText></Item>
                </List>
                <SubTitle>관심기술</SubTitle>
                <List>
                    <Item>HTML</Item>
                    <Item>CSS</Item>
                    <Item>JavaScript</Item>
                </List>
                <SubTitle>한마디</SubTitle>
                <Text>기초를 탄탄하게 다져서 더 나은 개발자 되겠습니다!</Text>
            </Details>
        </Container>
    </>   
    );
}

export default App;

그래서 이런 결과물을 만들었는데 뭐가 문젠지 사진이 안뜬다....
이렇게 보인다.......

일단 문제점은 사진 파일을 같은 폴더에 넣어두지 않았고
태그 안에 <img>라고 써둬서 아마 안된 것 같다 ㅎ...

진짜 결과물 ㅎ..

이걸 다 만들고 생각이 들었는데 왜 이렇게 컴포넌트를 많이 넣었는지 모르겠다... <h2 style={{margin:"10px 0 5px"}}> 처럼 짧은 건 굳이 만들이유가 없는 거 같은데... 흠... 아무 생각 없이 css파일 그대로 따오다가... 불상사가 발생한거 같다......... 아무리 생각해도 읽기가 힘든 것 같다... 앞으로는 만들기 전에 구조 생각을 잘 하고 만들기 시작해야될 것 같다....

profile
ㅡ.ㅡ

3개의 댓글

comment-user-thumbnail
2026년 4월 7일

리액트 연결법까지 작성하셔서 다시 상기시키는데 도움이 많이 됐어요!
글 잘 읽었습니다!!

답글 달기
comment-user-thumbnail
2026년 4월 7일

저도 사진이 안 떴는데 해결방법 감사합니다!!

답글 달기
comment-user-thumbnail
2026년 4월 7일

으로 버튼 코드 적으셔서 그런지 버튼이 참 이뻐요! 수고하셨습니다~

답글 달기