[TIL] React를 배워야하는 이유

신재욱·2023년 3월 14일
0
post-thumbnail

📒 오늘 공부한 내용

🔍수업목차

[2-1] React를 배워야하는 이유
[2-2] React 컴포넌트
[2-3] 클래스형 컴포넌트 vs 함수형 컴포넌트
[2-4] React-Hooks
[2-5] state 친구들 (state, setState, useState)

✅ React를 배워야하는 이유


대표적인 프론트엔드 도구로는 React, Angular, Vue가 있다.
이 가운데, React를 배워야 하는 여러가지 이유가 있다.

⏩ 가장 많은 사용자 수

⏩ 웹, 안드로이드, IOS, 데스크톱을 동시에 만들 수 있다.

React을 만드는 도구다.

React-Native모바일 앱을 만드는 도구다.

Electron은 React로 만들어진 웹사이트를 한글, PPT와 같은 데스크톱 프로그램에서 실행되도록 하는 도구다.

✅ React 컴포넌트


컴포넌트란 UI 또는 기능을 부품화해서 재사용 가능하게 하는 것

동일한 UI를 재활용하고, 안에 데이터와 이미지만 바꿔준다.

💡 컴포넌트는 복사/붙여넣기와는 다르다. 컴포넌트는 원본 하나를 만들어서 뿌려주는 개념이다.

⏩ 리액트 컴포넌트를 만들 때

import React from 'react';

⏩ 코드의 최하단

export default Hello;

⏩ App.js

import React from 'react';
import Hello from './Hello';

function App() {
  return (
    <div>
      <Hello />
    </div>
  );
}

export default App;

✅ 클래스형 컴포넌트 vs 함수형 컴포넌트


React에서 컴포넌트 작성 방법은 2가지가 있다.

⏩함수형 컴포넌트란?

함수형 컴포넌트란 함수를 기반으로 작성하는 컴포넌트다.
기존에 사용했던 클래스형 컴포넌트에 비해 휠씬 짧고 직관적인 코드를 짤 수 있다.

💡 그렇다면 왜 함수형 컴포넌트로 바꿔야할까?

  • 클래스의 문법이 어렵다.
  • 축소가 어렵다.
  • reloading의 신뢰성이 떨어진다.
  • 최신 기술의 적용이 효과적이지 않다.

💡 함수형이 훠씬 간단하나 클래스형 컴포넌트를 알아야하는 이유

  • 기존에 클래스형으로 만든 큰 프로젝트를 모두 함수형으로 바꾸기 어렵다.
  • 클래스 형으로 만들었지만, 부분 부분 함수형으로 변경하는 경우
  • 내가 검색한 자료가 클래스형인 경우

✅ React-Hooks


함수형 컴포넌트 그 자체만으로는 클래스형 컴포넌트의 모든 기능을 흉내낼 수 없다.

함수형 컴포넌트에서도 클래스형 컴포넌트와 동일한 기능을 사용 가능하도록 도구를 만들어 주었습니다. 이 도구를 Hooks(훅) 이라고 부른다.

Hooks 는 리액트 v16.8 에 새로 도입된 기능이다. 함수형태의 컴포넌트에서 사용되는 몇가지 기술을 Hook이라고 부른다.
함수형 컴포넌트에서도 상태 관리를 할 수 있는 useState, 그리고 렌더링 직후 작업을 설정하는 useEffect 등의 기능 등을 제공한다.

💡 Hook 의 기능

  • State Hook
  • useState

Effect Hook - useEffect

✅ state 친구들 (state, setState, useState)


state : 리액트 컴포넌트에서 데이터를 담기 위한 상자 즉, state는 컴포넌트에서 사용하는 변수

  • state : 컴포넌트에서 사용하는 변수(state)

  • setState : 컴포넌트에서 사용하는 변수(state)를 바꿔주는 기능

  • useState : 컴포넌트에서 사용하는 변수(state)를 만들어주는 기능

자바스크립트 변수 let(또는 상수 const) 를 사용과 state는 컴포넌트에서 사용 변수 비교

✦ 출처

📚 코드캠프

📌 오늘 실습 결과


이미지

JSX

import { useState } from "react"

import {
    Wrapper,
    Container,
    //--------------------> Box :)
    InPutBox,
    TwoBox,
    HeaderBox,
    AddressBox,
    YoutubeBox,
    AttachPicturesBox,
    MainSettingBox,
    RegistrationBox,
    //--------------------> 기타 :)
    Title,
    Label,
    Writer,
    Password,
    ZipButton,
    Pictures,
    RadioButton,
    RadioLabel,
    SubmitButton,
    PicturesOut,
    RadioOut,
    //--------------------> Text :)
    WriterText,
    PasswordText,
    TitleText,
    ContentsText,
    ZipText,
    AddressText,
    YoutubeText,
} from "../../styles/index";

export default function BoardsNewPage() {


    //-------------------------------------------------------> Input에 들어가는 문구 :)
    const [writer, setWriter] = useState("")
    const [password, setPassword] = useState("")
    const [title, setTitle] = useState("")
    const [contents, setContents] = useState("")
    const [zip, setZip] = useState("07250")
    const [youtube, setYoutube] = useState("")

    //---------------------------------------------------------> Input error :(
    const [writerError, setWriterError] = useState("")
    const [passwordError, setPasswordError] = useState("")
    const [titleError, setTitleError] = useState("")
    const [contentsError, setContentsError] = useState("")
    const [zipError, setZipError] = useState("")

    //---------------------------------------------------------->

    function onWriter(event) {
        setWriter(event.target.value)
    }

    function onPassword(event) {
        setPassword(event.target.value)
    }

    function onTitle(event) {
        setTitle(event.target.value)
    }

    function onContents(event) {
        setContents(event.target.value)
    }

    //--------------------------------------------------------------->

    function onChangeSignup() {



        // 1. 검증하기

        if (writer === "") {
            setWriterError("작성자를 다시 작성해주세요.")
        }
        if (password === "" && password.length < 3) {
            setPasswordError("비밀번호를 다시 작성해주세요.")
        }
        if (title === "") {
            setTitleError("제목을 다시 작성해주세요.")
        }
        if (contents === "") {
            setContentsError("내용을 다시 작성해주세요.")
        }
        if (writer !== "" && password !== "" && title !== "" && contents !== "") {
            alert("회원가입을 축하합니다!!")
        }

    }

    //------------------------------------------------------------->HTML :)

    return (
        <Wrapper>
            <Container>
                <HeaderBox>
                    <Title>게시물 등록</Title>
                </HeaderBox>
                <TwoBox>
                    <Writer>
                        <Label>작성자</Label>
                        <WriterText type="text" onChange={onWriter} placeholder="이름을 작성해주세요." />
                        <div>{writerError}</div>
                    </Writer>
                    <Password>
                        <Label>비밀번호</Label>
                        <PasswordText type="password" onChange={onPassword} placeholder="비밀번호를 작성해주세요." />
                        <div>{passwordError}</div>
                    </Password>
                </TwoBox>
                <InPutBox>
                    <Label>제목</Label>
                    <TitleText type="text" onChange={onTitle} placeholder="제목을 작성해주세요." />
                    <div>{titleError}</div>
                </InPutBox>
                <InPutBox>
                    <Label>내용</Label>
                    <ContentsText type="text" onChange={onContents} placeholder="내용을 작성해주세요." />
                    <div>{contentsError}</div>
                </InPutBox>
                <AddressBox>
                    <Label>주소</Label>
                    <ZipText type="text" placeholder="07250" />
                    <ZipButton>우편변호 검색</ZipButton>
                    <AddressText type="text" placeholder="" />
                    <AddressText type="text" placeholder="" />
                </AddressBox>
                <YoutubeBox>
                    <Label>유튜브</Label>
                    <YoutubeText type="text" placeholder="링크를 복사해주세요." />
                </YoutubeBox>
                <AttachPicturesBox>
                    <Label>사진 첨부</Label>
                    <PicturesOut>
                        <Pictures>+</Pictures>
                        <Pictures>+</Pictures>
                        <Pictures>+</Pictures>
                    </PicturesOut>
                </AttachPicturesBox>
                <MainSettingBox>
                    <Label>메인 설정</Label>
                    <RadioOut>
                        <RadioButton type="radio" name="myaRadio" />
                        <RadioLabel>유튜브</RadioLabel>
                        <RadioButton type="radio" name="myaRadio" />
                        <RadioLabel>사진</RadioLabel>
                    </RadioOut>
                </MainSettingBox>
                <RegistrationBox>
                    <SubmitButton onClick={onChangeSignup}>등록하기</SubmitButton>
                </RegistrationBox>
            </Container>
        </Wrapper>
    );
}

CSS

import styled from "@emotion/styled";

export const Wrapper = styled.div`
  width: 1200px;
  /* height: 1847px; */
  border: 1px solid black;
  margin: 100px;
  padding-top: 80px;
  padding-bottom: 100px;
  padding-left: 102px;
  padding-right: 102px;
  display: flex;
  flex-direction: column;
  align-items: center;
  border: none;
  box-shadow: 0px 0px 10px gray;
`;

export const Container = styled.div`
width: 1000px;
`;

export const HeaderBox = styled.div`
font-weight: 700;
font-size: 36px;
line-height: 53px;
margin-bottom: 50px;
display: flex;
flex-direction: row;
justify-content: center;
cursor: pointer;
`;

export const InPutBox = styled.div`
margin-bottom: 50px;
display: flex;
flex-direction: column;
`;

export const TwoBox = styled.div`
margin-bottom: 50px;
display: flex;
flex-direction: row;
justify-content: space-between;
`;

export const AddressBox = styled.div`
`;

export const YoutubeBox = styled.div`

`;

export const AttachPicturesBox = styled.div`

`;

export const MainSettingBox = styled.div`

`;

export const RegistrationBox = styled.div`
display: flex;
align-items: center;
justify-content: center;
`;


export const Title = styled.div`

`;

export const Label = styled.div`
font-weight: 500;
font-size: 16px;
margin-bottom: 10px;
`;

export const Writer = styled.div`

`;


export const WriterText = styled.input`
width: 486px;
height: 52px;
padding-left: 20px;
`;

export const Password = styled.div`

`;

export const PasswordText = styled.input`
width: 486px;
height: 52px;
padding-left: 20px;
`;

export const TitleText = styled.input`
width: 1000px;
height: 52px;
padding-left: 20px;
`;

export const ContentsText = styled.input`
width: 1000px;
height: 480px;
display: flex;
padding-bottom: 430px;
padding-left: 20px;
`;

export const ZipText = styled.input`
width: 77px;
height: 52px;
margin-right: 20px;
padding-left: 18px;
`;

export const ZipButton = styled.button`
width: 124px;
height: 52px;
background: #000000;
color: white;
border-radius: 3px;
border: none;
cursor: pointer;

`;

export const AddressText = styled.input`
width: 1000px;
height: 52px;
margin-top: 15px;
margin-bottom: 20px;
`;

export const YoutubeText = styled.input`
width: 1000px;
height: 52px;
margin-bottom: 30px;
padding-left: 20px;
`;

export const PicturesOut = styled.div`
display: flex;
`;

export const Pictures = styled.div`
background-color: #BDBDBD;
width: 78px;
height: 78px;
margin-right: 20px;
margin-top: 10px;
margin-bottom: 30px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
&:hover {
  background: #aDaDaD;
  }
`;

export const RadioOut = styled.div`
display: flex;
margin-bottom: 50px;
`;


export const RadioButton = styled.input`
margin-left: 20px;
`;

export const RadioLabel = styled.div`
margin-left: 10px;
font-weight: 500;
font-size: 16px;
`;

export const SubmitButton = styled.button`
width: 179px;
height: 52px;
background: #FFe600;
border: none;
border-radius: 3px;
font-weight: 500;
font-size: 16px;
cursor: pointer;
&:hover {
  background: #FFd600;
  }
`;

profile
1년차 프론트엔드 개발자

0개의 댓글