- 라이브러리
└── React 관련 패키지
└── 외부 라이브러리- 컴포넌트
└── 공통 컴포넌트
└── 현재 컴포넌트 기준 상대적으로 먼 컴포넌트
└── 현재 컴포넌트 기준 상대적으로 가까운 컴포넌트- 함수, 변수 및 설정 파일
- 사진 등 미디어 파일
- CSS 파일
// example
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import Nav from './components/Nav/Nav';
import { APIs } from './config';
import logo from './assets/logo.png';
import './Main.scss';
import React from 'react';
const Footer = () => {
return (
<div>
{FOOTER_INFO.map(info => {
return (
<li key={info.id}>
<a href="">{info.content}</a>
</li>
);
})}
</div>
);
};
export default Footer;
const FOOTER_INFO = [
{ id: 1, content: '도움말' },
{ id: 2, content: '홍보 센터' },
{ id: 3, content: 'API' },
{ id: 4, content: '채용정보' },
];
const [catAge, setCatAge] = useState(0);
const [dogAge, setDogAge] = useState(0);
// const [totalAge, setTotalAge] = useState(0);
굳이 토탈 안만들어도 위의 두 state 이용해서 합계 만들 수 있음.
const user = {
name: '김코드',
age: '30',
job: '프로그래머',
};
const getUserInfo = ({ name, age, job }) => {
return `제 이름은 ${name}이고 나이는 ${age}살이며 ${job}입니다.`;
};
getUserInfo(user);
// ProductList.js
const ProductList = () => {
return (
<ul>
{PRODUCT_LIST.map(product => (
<li key={product.id}>
<ProductItem product={product} />
</li>
))}
</ul>
);
};
// ProductItem.js
const ProductItem = ({ product: { title, price, quantity } }) => {
return (
<>
<span>{title}</span>
<span>{price}</span>
<span>{quantity}</span>
</>
);
};
const Login = () => {
// const [idValue, setIdValue] = useState('');
// const [pwValue, setPwValue] = useState('');
const [inputValues, setInputValues] = useState({
email: '',
password: '',
});
// const handleEmail = event => {
// const { value } = event.target;
// setInputValues({ ...inputValues, email: value });
// };
// const handlePassword = event => {
// const { value } = event.target;
// setInputValues({ ...inputValues, password: value });
// }; 위 두 코드 합치면 아래처럼 됨.
const handleInput = event => {
const { name, value } = event.target;
//이벤트 타겟 객체가 구조분해 할당 됨.
//name = email, value = 입력값
setInputValues({ ...inputValues, [name]: value });
// 기존 inputvalues객체에 [name]= email 키의 값으로 입력값이 변경됨.
}; // 객체의 name이란 키에 value 부여.
return (
<div>
<input type="text" onChange={handleEmail} />
<input type="password" onChange={handlePassword} />
</div>
);
};
// After : 삼항 연산자 활용
const changeButtonColor = () => {
input.id.includes('@') && input.pw.length >= 5
? setIsValid(true)
: setIsValid(false);
};
// After : 논리 연산자 활용
const changeButtonColor = () => {
const isValid = input.id.includes('@') && input.pw.length >= 5;
setIsValid(isValid);
};
// Bad
<button style={{ color: isCommentButtonActive ? '#0095f6' : '#b5e1ff' }}>
로그인
</button>
// Good
import 'style.css';
<button className={isCommentButtonActive ? 'activated' : 'deactivated'}>
로그인
</button>
<a> 태그를 사용하면 페이지를 새로 불러오게 되면서 앱이 지니고 있는 상태가 초기화되고 렌더링 된 컴포넌트도 모두 사라지고 새로 렌더링을 해야 합니다. 반면, <Link>는 브라우저의 주소만 바꿀 뿐 페이지를 새로 불러오지 않습니다. 그러므로 렌더링 최적화를 위해서 <Link>를 사용해 주세요.
반복적으로 사용되는 색깔 변수나 mixin 등이 있다면 variables.scss, mixin.scss 등의 별도 파일로 분리하고 필요한 scss 파일에서 import 해서 사용하는 것도 좋습니다. 이렇게 모듈화하여 관리하면 나중에 수정 사항이 생길 때 하나의 파일만 수정하면 되기 때문에 유지 보수에 좋습니다.
// style/variables.scss (예시코드)
theme-background: #f6f4f1;theme-white: #fff;
theme-black: #1c1c1e;theme-red: #ff0000;
$theme-blue: #007aff;
// 변수를 사용하는 scss 파일
@import "../../styles/variables.scss";
.main {
.title {
color: $theme-red;
}
}