22.04.14(목)
스파르타코딩클럽 리액트 심화반 - 1주차 과정
기본 프로젝트 세팅 : 해당 velog 참고
도움되는 크롬 익스텐션
도움되는 VSCode 확장
기본 화면 세팅시 사용할 라이브러리
build
: 빌드 후 결과물이 여기에 생성node_modules
: 우리가 설치한 패키지들public
: 가상 돔이 들어갈 빈 껍데기 html(index.html)이 들어있는 폴더src
: 실제 소스 코드가 들어갈 폴더입니다.컴포넌트 쪼개기
최소단위 컴포넌트 만들기 (폴더 구조에서 최소단위:element, 중간단위:component)
예시1
// elements > Image.js
import React from "react";
import styled from "styled-components";
const Image = (props) => {
const {shape, src, size} = props
const styles = {src, size}
// props에서 받은 분류를 통해 전혀 다른 값을 return함
if (shape === "circle") {
return(
<ImageCircle {...styles}></ImageCircle>
)
}
if (shape === "rectangle"){
return(
<AspectOutter>
<AspectInner {...styles}/>
</AspectOutter>
)
}
return(
<React.Fragment/>
)
}
// 해당 값이 넘어오지 않았을 때, 기본값을 설정해 놓음
// 오류를 막을 수는 있지만, 데이터가 수정되었는지 여부는 판단하기 힘듦
Image.defaultProps = {
shape: "circle",
src: "https://velog.velcdn.com/images%2Fgwichanlee%2Fpost%2Fb467e51c-2503-430d-ab89-0dd806f2a21e%2Ftest1.jpg",
size: 36,
}
// styled-component 사용시에 "--"를 앞에 붙여 변수처럼 활용할 수 있다.
// styled-component 사용할 때 해당 요소에 넘긴 props를 아래와 같이 활용할 수 있다.
const ImageCircle = styled.div`
--size: ${(props) => props.size}px;
width: var(--size);
height: var(--size);
border-radius: var(--size);
background-image: url("${(props) => props.src}");
background-size: cover;
margin: 4px;
`;
// div를 2개 사용하는 것을 통해 사진을 4:3 비율로 하는것을 강제함
const AspectOutter = styled.div`
width: 100%;
min-width: 250px;
`
const AspectInner = styled.div`
position: relative;
padding-top: 75%;
overflow: hidden;
background-image: url("${(props) => props.src}");
background-size: cover;
`
export default Image
import React from "react";
import styled from "styled-components";
const Grid = (props) => {
// children 값은 설정해주지 않아도 알아서 넘어감 / 안에 있는 하위 요소를 지정
const {is_flex, width, margin, padding, bg, children} = props
const styles = {is_flex, width, margin, padding, bg}
return(
<React.Fragment>
<GridBox {...styles}> {children} </GridBox>
</React.Fragment>
)
}
Grid.defaultProps = {
children: null,
is_flex: false,
width: "100%",
padding: false,
margin: false,
bg: false,
}
// align-items : center; 상하 정렬 , justify-content : space-between; 좌우 양쪽 정렬
// 3항연산자 사용시, 값이 있다면 (ex>"12px") true 처리함
const GridBox = styled.div`
width: ${(props) => props.width};
height: 100%;
box-sizing: border-box; // 박스 사이즈 계산시, padding 과 border-width 까지 전부 포함
${(props) => props.padding ? `padding : ${props.padding};` :""}
${(props) => props.padding ? `margin : ${props.margin};` :""}
${(props) => props.padding ? `background-color : ${props.bg};` :""}
${(props) => props.is_flex
? `display : flex; align-items : center; justify-content : space-between;`
: ""
}
`
export default Grid;
import React from "react";
import {Grid, Image, Text} from "../elements/index.js"
const Post = (props) => {
return(
<React.Fragment>
<Grid>
<Grid is_flex> // is_flex 안에 있는 것들에 flex, space-between 적용
<Image shape="circle" src={props.src}/> // Image에 circle 분류의 형태로 나옴
<Text bold>{props.user_info.user_name}</Text>
<Text>{props.insert_dt}</Text>
</Grid>
<Grid padding="16px">
<Text>{props.contents}</Text>
</Grid>
<Grid>
<Image shape="rectangle" src={props.src}/> // Image에 rectangle 분류의 형태로 나옴
</Grid>
<Grid padding="16px">
<Text bold>댓글 {props.comment_cnt}개</Text>
</Grid>
</Grid>
</React.Fragment>
)
}
// 아직 구현되지 않은 기본값 설정
Post.defaultProps = {
user_info: {
user_name: "Steve",
user_profile: "https://velog.velcdn.com/images%2Fgwichanlee%2Fpost%2Fb467e51c-2503-430d-ab89-0dd806f2a21e%2Ftest1.jpg"
},
image_url: "https://velog.velcdn.com/images%2Fgwichanlee%2Fpost%2F5cc3bbe0-550a-4cb7-8804-467f420f6002%2Ftest2.jpg",
contents: "예시입니다.",
comment_cnt: "0",
insert_dt: "2022-04-14 01:00:00",
}
export default Post;