본문 바로가기
Framework/React

React 기초 지식

by cariño 2022. 9. 5.
728x90
반응형

Node.js( javascript runtime), npm(node package manager) 설치

IDE(Integrated Development Environment)로 vscode 설치


[React CDN 사용]

<index.html>

DOM Container(Root DOM Node) 추가하기

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React</title>
</head>
<body>
    <h1>리액트 사용해보기</h1>
    <div id="root"></div>

    <!-- 리액트 가져오기 -->
    <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

    <!-- 리액트 컴포넌트 가져오기 -->
    <script src="MyButton.js"></script>
</body>

 

[create-react-app 사용]

Node.js v14.0.0 이상

npm v6.14.0 이상

 

npx : create-react-app <your-project-name>

npx create-react-app my-app으로 설치

 

# 경로 변경 ( change directory)

$ cd my-app

 

# 애플리케이션 실행

$ npm start  - 로컬 환경 실행

 

 


[JSX]

A syntax extension to JavaScript

자바스크립트 확장 문법

JavaScript + XML/HTML

const element = <h1>Hello, world!</h1>

 

[JSX의 역할]

  • XML/HTML을 Javascript코드로 변환 시킨다. 
  • React.createElement
class Hello extends React.Component {
    render(){
        return <div>Hello {this.props.towhat}</div>
    }
}

ReactDOM.render(
    <Hello towhat = 'World'/>,
    document.getElementById('root')
)

 

<JSX를 사용하지 않은 코드 ▼>

class Hello extends React.Component {
    render(){
        return React.createElement('div', null, `Hello ${this.props.toWath}`)
    }
}

ReactDOM.render(
    React.createElement(Hello, { toWath: 'World' }, null),
    document.getElementById('root')
)

 

React.createElement를 사용했을 때 들어가는 parameter

React.createElement(
    type,
    [props],
    [...children]
)

엘리먼트의 유형 : html태그 , 또다른 컴포넌트 등

props : 속성

..children : 자식 엘리먼트

 

[JSX의 장점]

//JSX사용함
<div>Hello {name}</div>

//JSX사용안함
React.createElement('div', null, `Hello, ${name}`)
  • 가독성 향상 (유지 보수 관점에서 버그를 발견하기 쉬움)
  • Injection Attacks 방어: 입력창에 소스코드를 입력하여 해당 코드가 실행되도록 만듬

 

[JSX 사용법]

모든 자바스크립트 문법을 지원한다. XML/HTML { JS } XML/HTML

XML/ HTML 코드 중간에 중괄호를 사용해서 Javscript 변수나 함수를 사용할 수 있다. 

const elem = <div tabIndex="0"></div>
const elem = <img src={user.avatarUrl}></img>

- 태그 속성의 값을 넣고 싶을 때 

const elem (
    <div>
        <h1>children1</h1>
        <h2>children1</h2>
    </div>
)

- 자식을 정의하는 방법


[Element]

엘리먼트의 개념과 역할 / 렌더링 되는 과정

 

Element란?

어떤 물체를 구성하는 성분을 말한다. 

React Element는 리액트 앱을 구성하는 요소를 정의한다. 

즉,  리액트 앱을 구성하는 작은 블록들을 말한다. 

 

리액트와 DOM 앨리먼트의 차이점?

리액트 Virtual DOM은 React Element가 렌더링이 되면 Browser DOM의 돔 앨리먼트가 된다.

실제 화면에서 기술하는 DOM앨리먼트가 만들어진다. 

 

리액트 앨리먼트의 생김새

리액트 앨리먼트는 자바스크립트 객체 형태로 존재한다.

일반적인 자바스크립트 객체이다. 

이 객체는 마음대로 변경할 수 없는 불변성이다. 

 

immutable한 특징

- 변하지 않은 성질을 갖고 있다. - 한번 생성된 앨리먼트는 children이나 attributes를 바꿀 수 없다. - component (붕어빵 틀) 붕어빵(element)

 

그렇다면 눈에 보이는 것을 기술하는데 화면 갱신은 어떻게?

새로운 내용을 위해서는 기존 앨리먼트 부분을 새로 만든 앨리먼트로 바꾼다. 이를 위해서 가상 돔을 사용한다. virtual DOM은 변경된 부분을 계산해서 바뀐 부분만 변경해준다. 

 

상태관리와 더불어 화면이 얼마나 갱신했는지에 대해서 성능에 큰 영향을 미치게 된다.앨리먼트가 새로 생성된다는 점을 기억하고 있으면 효율적인 개발을 할 수 있다. 

 

//React elements 생김새
{
    type: 'button',
    props: {
        className: 'bg-green',
        children: {
            type: 'b',
            props: {
                children: 'hello, element!'
            }
        }
    }
}

 

//리액트 앨리먼트가 렌더링 된 DOM 앨리먼트화면

<button class="bg-green">
    <b>
        hello, element! 
    </b>
</button>

 

createElement가 동작되는 과정

컴포넌트 렌더링을 위해서 모든 컴포넌트가 createElement 함수를 통해 앨리먼트로 변환된다는 것을 기억할 것!
function Button(props){
    return(
        <button className ={`bg-${props.color}`}>
            <b>
                {props.children}
            </b>
        </button>
    )
}

function confirmDialog(props){
    return(
        <div>
            <p>내용을 확인하였으면 확인 버튼을 눌러주세요.</p>
            <Button color="green">확인</Button>
        </div>
    )
}
 
컨펌다이얼로그 컴포넌트가 버튼 컴포넌트를 포함하고 있다.
//컨펌 다이얼로그 앨리먼트의 모습
 {
    type: 'div',
    props: {
        childrend: {
            type: 'p',
            props: {
                children: '내용을 확인하였으면 확인 버튼을 눌러주세요.'
            }
        },
        {
            type: Button,
            props{
                color: 'green',
                children: '확인'
            }
        }
    }
 }

 

[Elements 렌더링하기]

<div id ="root"></div>

이 코드는 리액트앱에 필수적으로 들어간다. 

모든 앨리먼트는 root DOM 노드에 모두 들어가있다. 

 

생성된 앨리먼트를 root DOM에 렌더링 시킨다. 

 


 

React Components

객체지향에서 나오는 class와 instance 개념과 비슷하다.

클래스라는 붕어빵 틀에서 실제 붕어빵이 나오는 것과 같다.

react component는 계속해서 붕어빵을 생성할 수 있다. 

 

[Props]

- 컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체이다. 

- 부모가 자식컴포넌트에게 전달해 주는 값

입력을 받는 props 는 property이다. 

컴포넌트의 모습과 속성을 결정하는것이 결정하는 것이  props이다.

 

컴포넌트에 데이터를 전달하고 전달 된 데이터에 따라 다른 모습의 element를 화면에 렌더링 하고싶을 때

해당 데이터를 props에 넣어서 전달하는 것이다.

 

props는 붕어빵에 들어가는 재료처럼 

눈에 들어가는 글자나 색상, 이미지 등 각자 다른 컴포넌트의 모습을 변경 할 수 있다. 

 

 

[특징 및 사용법]

Read-Only

값을 변경 할 수 없다. 

엘리먼트를 생성하기 위해서 사용하는 props

 

엘리먼트를 생성중에 props의 값은 변경 할 수 없다. 

붕어빵이 다 구어진 이후에 속재료를 바꿀 수 없는 이유와 마찬가지이다. 

 

 만약 다른 props의 값으로 엘리먼트를 생성하려면?

새로운 값을 컴포넌트에 전달해서 새로 Elemnet를 생성한다. 이과정에서 엘리먼트를 다시 렌더링함

 

* 짚고 넘어갈 js부분

//pure 
function sum(a, b){
    return a + b
}​

[Pure 함수]
함수의 출력 결과가 오로지 입력 결과에 따라 결정되는 함수
입력값(input)을 변경하지 않으며, 같은 입력값에 대해서는 항상 같은 출력값(output)을 리턴
외부와 상호작용 하는 경우는 외부의 상태가 함수의 실행 과정에 영향을 미칠 수 있으므로 순수 함수가 아닌 것으로 간주한다.

//impure 

function withDraw(accout, amount){
    accout.totla -= amount
}

//입력으로 받은 accout의 값이 변경된다.​

[Impure]
입력값(input)을 변경

 

모든 리액트 컴포넌트는 그들의 props에 관해서 pure함수 같은 역할을 해야한다. 

-> 모든 리액트 컴포넌트는 Props를 직접 바꿀 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줄 것!

 

리액트에서 입력을 받는 Props는 Javascript의 함수에서 Parameter와 같다. 

함수가 Pure하다는 것은 함수의 입력값인 파라미터를 바꿀 수없다는 의미를 포함하고 있다. 

리액트에서는 Props의 값을 바꿀 수 없다는 의미다. 

 

pure함수는 같은 입력값에 대해서는 항상 같은 결과를 보여줘야 하기 때문에

리액트 컴포넌트 관점에서 같은 Props에대해서 같은 결과를 보여줘야 한다는 의미이다.

=> 엘리먼트 리턴

 

[사용법]

jsx 사용 시 중괄호를 사용하면 무조건 javascript 코드가 사용된다.

마찬가지로 props에 값을 넣을 때 문자열 이외에 다른 컴포넌트, 정수, 변수가 들어갈 때 중괄호를 이용해서 묶어줘야 한다.  (문자열도 중괄호로 묶어도 상관없다)

JSX를 사용하면 간단하게 Props를 넣을 수 있다. 

 

function App(props){
    return(
        <Profile 
            name = "지니"
            introdution = "hey hi"
            vieCount = {1500}
        />
    )
}

 

속성의 값들이 Profile 컴포넌트의 props로 전달된다.

props는 아래와 같이 자바스크립트 객체와 같은 형태로 변환된다.

{
    name = "비니로그"
    introdution = "hey hi"
    vieCount = 1500
}

 

중괄호를 이용해서 props의 값으로 컴포넌트도 넣을 수 있다. 

function App(props){
    return(
        <Layout 
            width = {2560}
            height = {1440}
            header = {
                <Header title="비니 티스토리"/>
            }
            footer = {
                <Footer />
            }
        />
    )
}

 

 

 

JSX를 사용하지 않는다면?

 


[Component만들기 / 렌더링]

Component를 만드는 2가지 방법

- Class Component

- Function Component / Hook

 

class컴포넌트 / 라이프 사이클 잘 이해할 것

 

 

[함수 컴포넌트]

function Welcome(props){
    return <h1>안녕, {props.name} </h1>
}

모든 리액트 컴포넌트는 퓨어함수같은 역할을 해야한다. 

하나의 프롭스 객체를 받아서 리액트 엘리먼트를 리턴하기 때문에 리액트 컴포넌트라고 할 수 있다.

간단한 코드가 장점이다.

 

[클래스 컴포넌트]

함수 컴포넌트에 비해 몇 가지 코드가 추가된다.

리액트 모든 컴포넌트는 React.Component 클래스를 상속받아서 컴포넌트를 만든다. 

 

 

[컴포넌트 렌더링]

- 컴포넌트 이름은 항상 대문자로 시작해야 한다. 소문자로 시작하면  DOM태그로 인식한다. 

- 컴포넌트로부터 앨리먼트를 만든 후 앨리먼트를 렌더링 시킨다.  

fucntion Welcome(props){
    return <h1>안녕, {props.name}</h1>
}

const element = <Welcome name="인제" />
ReactDOM.render(
    element,
    document.getElementById('root')
)
  •  Welcome 함수 컴포넌트 생성 
  • element를 파라미터로 ReactDOM.render함수를 호출한다.
  • 리액트는 Welcome컴포넌트에 {name:"인제"} props를 넣어서 호출한다.
  • 그 결과로 리액트 element가 생성된다. => 실제 DOM에 렌더링되어 브라우저에서 볼 수 있게 된다.

 

[컴포넌트 합성과 추출]

복잡한 화면을 여러 개의 Component로 나눠서 구현이 가능하다. 

 

<컴포넌트 합성>

function Welcome(props){
  return <h1>안녕, {props.name}</h1>
}

function App(props) {
  return (
    <div>
      <Welcome name="Mike">
      <Welcome name="Steve">
      <Welcome name="Jane">
    </div>
  )
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

 

<컴포넌트 추출>

여러개의 컴포넌트로 나눌수도 있다. 

큰 컴포넌트에서 일부를 추출해서 새로운 컴포넌트도 생성할 수 있다. 

기능단위와 재사용성을 고려해서 추출한다. 

 

- 재사용성이 높아진다. 

컴포넌트가 작아질수록 해당 컴포넌트의 기능과 목적이 명확해진다.

props도 단순해지기 때문에 다른 곳에서도 사용할 수 있다.

 

- 개발 속도가 향상된다. 

재사용성이 올라가면서 개발 속도 또한 함께 올라간다. 

//컴포넌트 추출 전 
fucntion Commnet(props){
    return (
        <div className="commnet">
            <div className="user-info">
                <img className="avatar"
                    src={props.user.avataUrl}
                    alt={props.user.name} 
                />
                <div className="user-info-name">
                    {props.author.name}
                </div>
            </div>

            <div className="commnet-text">
                {props.text}
            </div>
        </div>
    )
}

 

//Avatar추출
fucntion Avatar(props){
    return (
        <img className="avatar"
            src={props.user.avataUrl}
            alt={props.user.name} 
        />
    )
}

//UserInfo 추출
fucntion UserInfo(props){
    return (
        <div className="user-info">
            <Avatar user={props.user} />
            <div className="user-info-name">
                {props.user.name}
            </div>
        </div>
    )
}

//추출된 컴포넌트를 사용 한 Commnet 컴포넌트
fucntion Commnet(props){
    return (
        <div className="commnet">
            <UserInfo user={props.author} />
            
            <div className="commnet-text">
                {props.text}
            </div>
        </div>
    )
}

728x90

'Framework > React' 카테고리의 다른 글

conditional rendering  (0) 2022.10.11
리액트에서 setState는 비동기로 동작 ??  (1) 2022.10.03
React TodoList 만들기  (0) 2022.10.03
useEffect()  (1) 2022.09.29
class 컴포넌트에서 function 컴포넌트로  (0) 2022.09.26

댓글