[React] 4. 리액트 컴포넌트

ㅎㅎ·2023년 8월 1일
0

React

목록 보기
6/11

JSX 문법 정리

참고 사이트

유의사항

  • 함수 이름의 시작은 대문자여야한다
  • 컴포넌트는 하나의 태그만 반환해야한다
    • 다수의 태그를 반환하고 싶다면 부모 태그로 감싸야한다.
    • 리액트 내부적으로는 프래그먼트를 사용함 Fragment
  • HtML에서는 class라고 하지만 리액트에서는 className이라 함
  • 자바스크립트를 사용할 땐 중괄호를 써야한다.


JSX 문법 정리 (심화)

  • App.js
import './App.css';

function App() {
  const name = '앨리';
  const list = ['우유', '딸기', '바나나', '요거트'];
  return (
    <>
      <h1 className='orange'>{`Hello! ${name}`}</h1>
      <h2>Hello!</h2>
      <p>{name}</p>
      <ul>
        {
          // list.map((item) => (
          //   <li>{item}</li>
          // ))

          // list.map((item) => { return <li>{item}</li>})
          
          // 화살표 함수
          list.map(function(item) {
            return <li>{item}</li>;
          })
        }
      </ul>
      <img
      style={{width: '200px', height: '200px'}}
        src='https://images.unsplash.com/photo-1525431836161-e40d6846e656?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjB8fCVFRCU4QyU4QyVFQiU4RiU4NHxlbnwwfHwwfHx8MA%3D%3D&auto=format&fit=crop&w=600&q=60'
        alt=''
      />
    </>
    
  );
}

export default App;
  • App.css
.orange {
  color: orange;
}

컴포넌트 만드는 꿀팁

아래 코드의 문제 : 함수 명을 바꾸면 export에서도 바꿔줘야함

아래처럼 합칠 수 있음

Profile 첫 컴포넌트 만들기

사용한 Box Shadow 사이트: https://cssgenerator.org/box-shadow-css-generator.html

  • AppProfile.jsx
import './App.css';
import Profile from './components/Profile';

function AppProfile() {
  return (
    <>
      <Profile />
    </>
    
  );
}

export default AppProfile;
  • Profile.jsx
import React from 'react';

export default function Profile() {
    return (
        <div className='profile'>
            <img
            className='photo'
            src='https://images.unsplash.com/photo-1574158622682-e40e69881006?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=580&q=80'
                alt='avatar'
            />
            <h1>Hana</h1>
            <p>프론트엔드 개발자</p>
        </div>
    );
}
  • App.css
.orange {
  color: orange;
}

.profile {
  width: 300px;
  text-align: center;
  padding: 1rem;
  background-color: #ebebeb;
  border-radius: 20px;
  box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -webkit-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -moz-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
}

.photo {
  width: 200px;
  height: 200px;
  border-radius: 100%;
}

사용한 고양이 이미지 주소 :
https://images.unsplash.com/photo-1574158622682-e40e69881006?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=580&q=80

Props 사용해보기

위 코드는 사전에 지정한 Hana만 할 수 있기 때문에 재사용성이 떨어진다.

외부로부터 주어진 props를 사용해서 할 수 있도록 props에서 이미지의 주소와 이름과 직함을 전달 받는다.

  • AppProfile.jsx
import './App.css';
import Profile from './components/Profile';

function AppProfile() {
  return (
    <>
      <Profile
        image='https://images.unsplash.com/photo-1574158622682-e40e69881006?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=580&q=80'
        name='Hana'
        title='프론트엔드 개발자'
      />
      <Profile
        image='https://images.unsplash.com/photo-1583512603805-3cc6b41f3edb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80'
        name='Anna'
        title='백엔드 개발자'
      />
    </>
    
  );
}

export default AppProfile;
  • Profile.jsx (1)
import React from 'react';

export default function Profile(props) {
    return (
        <div className='profile'>
            <img
            className='photo'
            src={props.image}
                alt='avatar'
            />
            <h1>{props.name}</h1>
            <p>{props.title}</p>
        </div>
    );
}

props를 풀어쓸 수도 있음

  • Profile.jsx (2)
import React from 'react';

export default function Profile({image, name, title}) {
    return (
        <div className='profile'>
            <img
            className='photo'
            src={image}
                alt='avatar'
            />
            <h1>{name}</h1>
            <p>{title}</p>
        </div>
    );
}

사용한 강아지1 이미지 주소 :
https://images.unsplash.com/photo-1583512603805-3cc6b41f3edb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80
강아지2 이미지 주소 :
https://plus.unsplash.com/premium_photo-1661903055250-d4cd3d70f805?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80

  • App.css
.orange {
  color: orange;
}

.profile {
  width: 300px;
  text-align: center;
  padding: 1rem;
  background-color: #ebebeb;
  border-radius: 20px;
  margin-bottom: 1rem;
  box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -webkit-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -moz-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
}

.photo {
  width: 200px;
  height: 200px;
  border-radius: 100%;
}

🔥 새로운 개발자 태그 만들기

new 요소만들기

내가 직접 만들어보기

  • Profile.jsx
import React from 'react';

export default function Profile({image, name, title, newperson}) {
    return (
        <div className='profile'>
            <p className='newperson'>NEW</p>
            <img
            className='photo'
            src={image}
                alt='avatar'
            />
            <h1>{name}</h1>
            <p>{title}</p>
        </div>
    );
}
  • App.css
.newperson {
  width: fit-content;
  position: relative;
  top: 60px;
  left: 215px;
  text-align: center;
  font-weight: bold;
  padding: 0 5px;
  border-radius: 5px;
  background-color: rgb(134, 251, 206);
}

이렇게 뜨는데 모든 컴포넌트에 다 뜸

newperson이라는 props를 받아서 new 컴포넌트를 구별하자!

참고한 사이트 :
https://codingapple.com/unit/react-if-else-patterns-enum-switch-case/

  • AppProfile.jsx
import './App.css';
import Profile from './components/Profile';

function AppProfile() {
  return (
    <>
      <Profile
        image='https://images.unsplash.com/photo-1574158622682-e40e69881006?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=580&q=80'
        name='Hana'
        title='프론트엔드 개발자'
        boolnew={true}
      />
      <Profile
        image='https://images.unsplash.com/photo-1583512603805-3cc6b41f3edb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80'
        name='Anna'
        title='백엔드 개발자'
        boolnew={false}
      />
      <Profile
        image='https://plus.unsplash.com/premium_photo-1661903055250-d4cd3d70f805?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80'
        name='Bob'
        title='백엔드 개발자'
        boolnew={false}
      />
    </>
    
  );
}

export default AppProfile;
  • Profile.jsx
import React from 'react';

export default function Profile({image, name, title, boolnew}) {
    return (
        <div className='profile'>
            {
                `${boolnew}` === "true"
                ? <p className='newperson'>NEW</p>
                : null
            }
            <img
            className='photo'
            src={image}
                alt='avatar'
            />
            <h1>{name}</h1>
            <p>{title}</p>
        </div>
    );
}

이렇게 하니 됐다.

그런데 bool 타입 그대로 쓰는 방법은 없나?

아하!! 걍 중괄호 하나만 넣으면 됐었음

참고용 코드

  • AppProfile.jsx
import './App.css';
import Profile from './components/Profile';

function AppProfile() {
  return (
    <>
      <Profile
        image='https://images.unsplash.com/photo-1574158622682-e40e69881006?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=580&q=80'
        name='Hana'
        title='프론트엔드 개발자'
        isNew={true}
      />
      <Profile
        image='https://images.unsplash.com/photo-1583512603805-3cc6b41f3edb?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80'
        name='Anna'
        title='백엔드 개발자'
        isNew={true}
      />
      <Profile
        image='https://plus.unsplash.com/premium_photo-1661903055250-d4cd3d70f805?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=880&q=80'
        name='Bob'
        title='백엔드 개발자'
        isNew={true}
      />
    </>
    
  );
}

export default AppProfile;
  • Profile.jsx
import React from 'react';

export default function Profile({image, name, title, isNew}) {
    return (
        <div className='profile'>
            <img className='photo' src={image} alt='avatar' />
            {isNew && <span className='new'>New</span>}
            <h1>{name}</h1>
            <p>{title}</p>
        </div>
    );
}

자바스크립트의 &&연산자 :

앞의 조건이 참이면 뒤에를 리턴하고 아니면 null을 리턴
{isNew && New}
isNew가 true 일 때만 저 뒤에를 나오게 해줄거야

  • App.css
.orange {
  color: orange;
}

.profile {
  position: relative;
  width: 300px;
  text-align: center;
  padding: 1rem;
  background-color: #ebebeb;
  border-radius: 20px;
  margin-bottom: 1rem;
  box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -webkit-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -moz-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
}

.new {
  position: absolute;
  left: 70%;
  top: 10%;
  background-color: aquamarine;
  padding: 0.2rem 0.5rem;
  border-radius: 0.5rem;
  text-transform: uppercase;
  font-weight: bold;
}

.photo {
  width: 200px;
  height: 200px;
  border-radius: 100%;
}

🔥 아바타 컴포넌트 만들기

사용자의 사진이 따로 필요한 곳이 생겼을 때의 처리

직접 해보기

  • Profile.jsx
import React from 'react';
import Avartar from './Avartar';

export default function Profile({image, name, title, isNew}) {
    return (
        <div className='profile'>
            <Avartar image={image}/>
            {isNew && <span className='new'>New</span>}
            <h1>{name}</h1>
            <p>{title}</p>
        </div>
    );
}
  • Avartar.jsx
import React from 'react';

export default function Avartar({image}) {
    return (
        <img className='photo' src={image} alt='avartar' />
    );
}

참고용 코드

하하 강의의 코드와 내가 짠 로직이 동일하다.
(차이점: 강의에서는 new까지 컴포넌트 안으로 가져온다.)

  • Avartar.jsx
import React from 'react';

export default function Avartar({image, isNew}) {
    return (
        <div className='avartar'>
            <img className='photo' src={image} alt='avartar' />
            {isNew && <span className='new'>New</span>}
        </div>
    );
}
  • App.css
.orange {
  color: orange;
}

.profile {
  width: 300px;
  text-align: center;
  padding: 1rem;
  background-color: #ebebeb;
  border-radius: 20px;
  margin-bottom: 1rem;
  box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -webkit-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
  -moz-box-shadow: 5px 5px 5px 0px rgba(0,0,0,0.43);
}

.photo {
  width: 200px;
  height: 200px;
  border-radius: 100%;
}

.avartar {
  position: relative;
  width: 200px;
  height: 200px;
  margin: auto; 
}

.new {
  position: absolute;
  left: 70%;
  top: 10%;
  background-color: aquamarine;
  padding: 0.2rem 0.5rem;
  border-radius: 0.5rem;
  text-transform: uppercase;
  font-weight: bold;
}

메모

npm을 사용하고 싶다면 아래 두 명령어를 실행:

npm install
npm start

yarn을 사용하고 싶다면 아래 두 명령어를 실행:

yarn install
yarn start

profile
Backend

0개의 댓글