Event

- 특정 사건을 의미
- 예) 사용자가 버튼을 클릭한 사건 : 버튼 클릭 이벤트

 

 

 

DOM의 Event와 리액트의 Event 비교

DOM의 Event
리액트의 Event

 

- 리액트의 onClick은 카멜 표기법으로
- 함수 전달 방식에 약간 차이있음

 

Event Handler

- 어떤 사건이 발생하면, 사건을 처리하는 역할
- Event Listener라고 부르기도 함

 

 

- Arrow function 사용은 권장되는 방식이 아니다. 그러니 Bind 혹은 Class fields syntax 를 사용하는 것이 좋다.

 

 

Arguments 전달하기

- Arguments는 함수에 전달할 데이터, Event Handler에 전달한 데이터, 매개변수 역할

위는 Arrow function 을 사용하여 Event Handler에 Arguments를 전달한 것이고, 아래는 bind를 사용하였다. Arrow function으로 사용한 방식은 명시적으로 event를 두번재 매개변수로 넣어주었고, 아래 bind 방법은 Event가 자동으로 id 이후에, 두번째 매개변수로 전달된다. 위의 두 방식은 Class 컴포넌트에서 사용하는 방식이므로 지금은 거의 사용하지 않는다.

 

 

 

 

함수 컴포넌트에서 사용법. 참고로 매개변수의 순서는 원하는대로 변경해도 상관없다.

 

 

 

 

실습 : 클릭 이벤트 처리하기

1) Bind를 사용한 방식 (Class Component)

import React from "react";

class ConfirmButton extends React.Component {
    constructor(props) {
        super(props);

        // 확인여부 저장위함 (초깃값 false)
        this.state = {
            isConfirmed: false,
        };

        this.handleConfirm = this.handleConfirm.bind(this);
    }

    // Event Handler : 버튼을 누르면 실행됨
    handleConfirm() {
        this.setState((prevState) => ({
            isConfirmed: !prevState.isConfirmed,
        }));
    }

    render() {
        return (
            <button
                onClick={this.handleConfirm}
                disabled={this.state.isConfirmed}
            >
                {this.state.isConfirmed ? "확인됨" : "확인하기"}
            </button>
        );
    }
}

export default ConfirmButton;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import ConfirmButton from './chapter_08/ConfirmButton';


ReactDOM.render(
  <React.StrictMode>
  <ConfirmButton />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

실행하면, 확인하기 버튼 하나가 생성되는데, 누르면 확인됨으로 변경되고, 버튼이 비활성화 되는 것을 확인할 수 있다.

 

 

 

 

2) Class fields syntax 를 사용한 방식 (Class Component)

import React from "react";

class ConfirmButton extends React.Component {
    constructor(props) {
        super(props);

        // 확인여부 저장위함 (초깃값 false)
        this.state = {
            isConfirmed: false,
        };
    }

    // Event Handler : 버튼을 누르면 실행됨
    handleConfirm = () => {
        this.setState((prevState) => ({
            isConfirmed: !prevState.isConfirmed,
        }));
    }

    render() {
        return (
            <button
                onClick={this.handleConfirm}
                disabled={this.state.isConfirmed}
            >
                {this.state.isConfirmed ? "확인됨" : "확인하기"}
            </button>
        );
    }
}

export default ConfirmButton;

 

bind를 사용한 부분을 지우고, 이벤트 핸들러를 Arrow function으로 변경한다. 실행결과 동일하게 작동된다.

 

 

 

 

3) 함수 컴포넌트로 바꿔보기 (권장)

- Class Component는 거의 사용하지 않기 때문에 이 방법을 가장 권장함

 

import React, { useState} from "react";

function ConfirmButton(props) {
    const [isConfirmed, setIsConfirmed] = useState(false);

    const handleConfirm = () => {
        setIsConfirmed((prevIsConfirmed) => !prevIsConfirmed);
    };

    return (
        <button onClick={handleConfirm} disabled={isConfirmed}>
            {isConfirmed ? "확인됨" : "확인하기"}
        </button>
    );
}

export default ConfirmButton;

 

state는 useState() 훅을 사용해 처리, EventHandler는 Arrow function 이용해 만듦. 작동시킨 결과, 역시 동일한 결과가 나온다.

'React' 카테고리의 다른 글

[React] List 와 Key  (0) 2024.08.13
[React] Conditional Rendering  (0) 2024.08.12
[React] Hooks 실습  (0) 2024.08.07
[React] Hooks  (0) 2024.08.06
[React] State and Lifecycle  (0) 2024.08.03
import React, { useState } from "react";
// 카운트 기능
function useCounter(initialValue) {
    const [count, setCount] = useState(initialValue);

    const increaseCount = () => setCount((count) => count + 1);
    const decreaseCount = () => setCount((count) => Math.max(count -1, 0));

    return [count, increaseCount, decreaseCount];
}

export default useCounter;

우선 버튼을 누르면 카운트가 바뀌는 커스텀 훅을 작성한다. useState() 는 현재 카운트의 상태를 생성 및 업데이트 해주는 역할을 한다.

 

 

 

import React, { useState, useEffect } from "react";
import useCounter from "./useCounter";

const MAX_CAPACITY = 10;

function Accommodate(props) {
    const [isFull, setIsFull] = useState(false);
    const [count, increaseCount, decreaseCount] = useCounter(0);

    // 의존성 배열 없음 (마운트 된 직후 호출, 컴포넌트 업데이트 때마다 호출)
    useEffect(() => {
        console.log("=====================");
        console.log("useEffect() is called");
        console.log(`isFull: ${isFull}`);
    });

    // 의존성 배열 있음 (마운트 된 직후 호출, 카운트 값이 바뀔때 마다 호출)
    useEffect(() => {
        setIsFull(count >= MAX_CAPACITY);
        console.log(`Current count value: ${count}`);
    }, [count]);

    return (
        <div style={{ padding: 16 }}>
            <p>{`총 ${count}명 수용했습니다.`}</p>

            <button onClick={increaseCount} disabled={isFull}>
                입장
            </button>
            <button onClick={decreaseCount}>퇴장</button>

            {isFull && <p style={{ color : "red" }}> 정원이 가득찼습니다.</p>}
        </div>
    );
}

export default Accommodate;

useEffect()를 이용해보았다. 의존성 배열 있는것과 없는 것을 비교하기 위해 다음과 같이 작성하였다.

 

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import Accommodate from './chapter_07/Accommodate';


ReactDOM.render(
  <React.StrictMode>
  <Accommodate />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

인덱스에서 렌더링하는거 잊지 말고...

 

 

 

맨 처음에 콘솔창을 열어보면 컴포넌트가 생성되고, 카운트값의 초기값이 생성되었기에 두개의 useEffect() 훅이 마운트 된 직후에 호출된 걸 확인할 수 있다. 그리고 입장 버튼을 누르면, 컴포넌트가 업데이트되고, 카운트 값도 변경되니, 이 역시 두개의 useEffect() 훅이 호출된다.

 

 

 

 

그러나 정원이 꽉 차게 된다면, 일단 두개의 훅이 호출되는데, 그 후 또 하나의 useEffect() 훅이 호출된다. 이는 정원이 꽉 차게 되어 isFull의 상태가 변하기 때문에 컴포넌트가 업데이트 되어, 정원이 꽉 차게 되었다는 걸 알리는 useEffect() 훅이 호출된다. 하지만 count라는 의존성 배열이 있는 useEffect() 훅은 카운트 값의 변화가 없기 때문에 호출되지 않는다.

 

 

 

 

 

퇴장 버튼을 0이 될 때까지 누르고, 0이 되어서 계속 퇴장버튼을 눌러도 두개의 useEffect 훅 모두 호출되지 않는다. 의존성 배열인 count의 값이 변하는 것도 아니고, isFull의 상태 역시 변하는 것이 아니기 때문에 컴포넌트가 업데이트 되지 않기 때문이다.

'React' 카테고리의 다른 글

[React] Conditional Rendering  (0) 2024.08.12
[React] Event  (0) 2024.08.08
[React] Hooks  (0) 2024.08.06
[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01

Hooks

- 함수 컴포넌트는 클래스 컴포넌트와는 달리 state 사용이랑 Lifecycle 사용이 불가능하다. 그래서 이를 보완하기 위해 Hooks을 이용한다.
- 갈고리라는 뜻, 마치 갈고리를 거는 것처럼 끼워서 사용하는 듯함
- 이름 앞에 use로 시작해야 함(약속)

 

 

 

useState() : state를 사용하기 위한 Hook

- const [변수명, set함수명] = useState(초기값);

 

 

useEffect() : Side effect를 수행하기 위한 Hook

- Side effect = 효과, 영향
- useEffect(이펙트 함수, 의존성 배열);
- 의존성 배열이 []일 경우 mount, unmount 시 단 한 번씩만 실행됨
- 의존성 배열을 생략하면 컴포넌트가 업데이트 될 때마다 호출 됨



 

useMemo() : Memoized value를 리턴하는 Hook

- Memoization : 최적화를 위해, 비용이 높은, 연산량이 많은 함수의 호출 결과를 저장해놓았다가, 나중에 필요할 때 반환
- 의존성 배열을 넣지 않을 경우, 매 렌더링마다 함수가 실행 됨
- 의존성 배열이 빈 배열일 경우, 컴포넌트 마운트 시에만 호출 됨

 

 

useCallback() : useMemo() Hook과 유사하지만 값이 아닌 함수를 반환

- useCallback(함수, 의존성 배열);
- useMemo(() => 함수, 의존성 배열);
- 위 두줄의 코드는 동일한 역할을 한다.

 

 

useRef() : Reference를 사용하기 위한 Hook

- Reference : 특정 컴포넌트에 접근할 수 있는 객체
- refObject.current : current는 현재 참조하고 있는 Element
- const refContainer = useRef(초깃값);
- 변경가능한 current
- 내부의 데이터가 변경되었을 때 별도로 알리지 않는다.
- Callback ref는 내부의 데이터가 변경 시, 알림을 받을 수 있음



 

Hook의 규칙

- 무조건 최상위 레벨에서만 호출해야 한다.
- 컴포넌트가 렌더링될 때마다 매번 같은 순서로 호출되어야 한다.
- 리액트 함수 컴포넌트에서만 Hook을 호출해야 한다.

useEffect()가 if문 안에 있다. 잘못된 사용법이다. Hook은 무조건 최상위 레벨에서만 호출해야 한다.



 

Custom Hook 만들기

- 여러 컴포넌트에서 반복적으로 사용되는 로직을 Hook으로 만들어 재사용하는 방법
- 함수역할을 하지만 엄연히 Hook 이기 때문에 꼭 use로 시작해야 한다!
- 여러개의 컴포넌트에서 하나의 Custom Hook을 사용할 때 컴포넌트 내부에 있는 모든 state와 effects는 전부 분리되어 있다.
- 각 Custom Hook 호출에 대해서 분리된 state를 얻게 됨!
- 각 Custom Hook의 호출 또한 완전히 독립적이다.

온라인인지 오프라인인지 알려주는 컴포넌트이다. 사용자가 온라인인지 오프라인인지 알려주는 부분을 따로 추출하여, Custom Hook을 만들 예정이다.

 

 

다음과 같이 따로 추출해서 useUserStatus()라는 Custom Hook을 만들었다.

 

 

다음과 같이 함수마냥 사용하여 중복되는 부분에 붙여넣기 하면 된다.

비록 함수같은 역할을 하지만 엄연히 Hook이기 때문에 앞에 use로 시작하게끔 이름을 설정해야 한다.

 

 

Hook들 사이에서 데이터를 공유하는 방법

 

'React' 카테고리의 다른 글

[React] Event  (0) 2024.08.08
[React] Hooks 실습  (0) 2024.08.07
[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01
[React] Rendering Elements  (0) 2024.07.31

State (react의 핵심중의 핵심)

- 한글로 상태라는 뜻
- 리액트에서는 Component의 상태
- 리택트 Component에서 변경 가능한 데이터
- 렌더링이나 데이터 흐름에 사용되는 값만 state에 포함시켜야 함!
- State는 JavaScript 객체이다
- 직접 수정할 수 없다 (수정하면 안된다.)

- constructor (생성자)

 

 

 

 

Lifecycle

- 생명주기 라는 뜻
- 리액트 Component의 생명주기
- Component가 계속 존재하는 것이 아니라, 시간의 흐름에 따라 생성되고 업데이트 되다가 사라진다.

 

 

 

State 실습

import React from "react";

const styles = {
    wrapper: {
        margin: 8,
        padding: 8,
        display: "flex",
        flexDirection: "row",
        border: "1px solid grey",
        borderRadius: 16,
    },
    messageText: {
        color: "black",
        fontSize: 16,
    },
};

class Notification extends React.Component {
    constructor(props) {
        super(props);
        
        this.state = {};
    }

    render() {
        return (
            <div style={styles.wrapper}>
                <span style={styles.messageText}>{this.props.message}</span>
            </div>
        );
    }
}

export default Notification;
import React from "react";
import Notification from "./Notification";

const reservedNotifications = [
    {
        message: "안녕하세요 오늘의 일정을 알려드리겠습니다.",
    },
    {
        message: "점심식사 시간입니다.",
    },
    {
        message: "이제 곧 미팅이 시작됩니다.",
    },
];

var timer;

class NotificationList extends React.Component {
    constructor(props) {
        super(props);
        
        // 처음 빈 배열을 넣어 초기화
        this.state = {
            notifications: [],
        };
    }

    // setInterval을 이용하여 1초마다 정해진 작업
    // 미리 만들어둔 알림 데이터 배열 reservedNodification 로 부터
    // 알림 데이터를 하나씩 가져와서 state에 있는 notifications 배열에 넣고 업데이트
    componentDidMount() {
        const { notifications } = this.state;
        timer = setInterval(() => {
            if (notifications.length < reservedNotifications.length) {
                const index = notifications.length;
                notifications.push(reservedNotifications[index]);
                this.setState({ // state 업데이트를 위해 setState
                    notifications: notifications,
                });
            } else {
                clearInterval(timer);
            }
        }, 1000);
    }

    render() {
        return (
            <div>
                {this.state.notifications.map((notification) => {
                    return <Notification message={notification.message} />;
                })}
            </div>
        );
    }
}

export default NotificationList;

 

constructor는 일종의 생성자라고 보면 된다. 먼저 state()로 초기화 한 후, setInterval을 통해 배열에 원하는 데이터값을 하나씩 넣으면서 setState()로 업데이트를 한다. state()로는 업데이트를 하면 안된다.

 

 

 

1초에 하나씩 메세지가 생기는 걸 확인할 수 있다.

 

 

 

 

Lifecycle 실습

class Notification extends React.Component {
    constructor(props) {
        super(props);
        
        this.state = {};
    }

    componentDidMount() {
        console.log(`${this.props.id} componentDidMount() called.`);
    }

    componentDidUpdate() {
        console.log(`${this.props.id} componentDidUpdate() called.`);
    }

    componentWillUnmount() {
        console.log(`${this.props.id} componentWillUnmount() called.`);
    }

    render() {
        return (
            <div style={styles.wrapper}>
                <span style={styles.messageText}>{this.props.message}</span>
            </div>
        );
    }
}

생명 주기를 확인할 수 있는 함수를 작성한다. componentDidmount()는 마운트 되었을 시, componentDidUpdate()는 컴포넌트가 업데이트 되었을 시, componentWillUnmount()는 컴포넌트가 언마운트 되었을 시에 실행된다.

 

 

 

 

const reservedNotifications = [
    {
        id: 1,
        message: "안녕하세요 오늘의 일정을 알려드리겠습니다.",
    },
    {
        id: 2,
        message: "점심식사 시간입니다.",
    },
    {
        id: 3,
        message: "이제 곧 미팅이 시작됩니다.",
    },
];


/ .... /


    render() {
        return (
            <div>
                {this.state.notifications.map((notification) => {
                    return <Notification 
                            key={notification.id}
                            id={notification.id}
                            message={notification.message} />;
                })}
            </div>
        );
    }

헷깔리지 않도록 메세지에 id 값을 주고, 렌더링 시, Notification에 키와 아이디값을 요소에 설정한다.

 

 

그럼 다음과 같이 터미널의 콘솔창에 나타난다. 첫번째 메세지가 마운트되고, 2번째 메세지가 마운트되어 나타나면 첫번째 메세지도 업데이트 된다. 3번째 메세지가 마운트되어 나타나면, 1,2번 메세지 역시 업데이트된다.

 

 

 

 

    componentDidMount() {
        const { notifications } = this.state;
        timer = setInterval(() => {
            if (notifications.length < reservedNotifications.length) {
                const index = notifications.length;
                notifications.push(reservedNotifications[index]);
                this.setState({ // state 업데이트를 위해 setState
                    notifications: notifications,
                });
            } else {
                this.setState({
                    notifications: [],
                });
                clearInterval(timer);
            }
        }, 1000);
    }

but 컴포넌트가 언마운트되었을 시, componentWillUnmount() 함수를 실행하는데, 위의 작업은 componentWillUnmount()가 실행되지 않았다. 그 이유는 언마운트 된 컴포넌트가 없기 때문이다. 그래서 모든 업데이트가 끝난 후, 부분에 setState() 로 notifications 배열을 빈 배열로 만든다.

 

 

 

모든 작업 이후, notifications 배열이 빈 배열로 바뀌었기 때문에, 1,2,3번 메세지는 언마운트된다. 콘솔창에서 확인할 수 있다.

'React' 카테고리의 다른 글

[React] Hooks 실습  (0) 2024.08.07
[React] Hooks  (0) 2024.08.06
[React] Components 와 Props  (0) 2024.08.01
[React] Rendering Elements  (0) 2024.07.31
[React] JSX 의 장점과 사용법  (0) 2024.07.30

Components

작은 컴포넌트들이 모여서 하나의 컴포넌트를 구성하고 이런 컴포넌트들로 전체 페이지가 구성됨
Component가 붕어빵 틀이라면 Element는 붕어빵. 자바의 객체와도 같음

 

Props

prop은 리액트 Component의 property(속성)
붕어빵에 들어가는 재료라고 보면 됨

Props 의 특징
읽기 전용 - 값을 변경할 수 없다. (붕어빵 다 구워졌으니 속재료 변경 불가)
같은 Props에 대해서는 항상 같은 결과를 보여줌

Props 사용법
JSX 사용경우 (권장)

 


JSX 사용하지 않을 경우

 

 

 

Component 만들기

 

 

class component : React.Component를 상속받음

 


Component의 이름 짓는 법
- Component의 이름은 항상 대문자로 시작해야 한다!

Component 렌더링

 


Component 합성
- Component 안에 또 다른 Component


Component 추출
- 큰 Component 를 일부를 추출해서 새로운 Component를 만듦
- 재사용성 높아짐
- 개발속도 향상

 

 

실습 : 댓글 컴포넌트 만들기

import React from "react";

function Comment(props) {
    return (
        <div>
            <h1>제가 만든 첫 컴포넌트</h1>
        </div>
    );
}

export default Comment;
import React from "react";
import Comment from "./Comment";

function CommentList(props) {
    return (
        <div>
            <Comment />
        </div>
    );
}

export default CommentList;
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import CommentList from './chapter_05/CommentList';

setInterval(() => {
  ReactDOM.render(
    <React.StrictMode>
    <CommentList />
    </React.StrictMode>,
    document.getElementById('root')
  );
}, 1000);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

댓글 리스트 컴포넌트 안에 댓글 컴포넌트가 포함되어 있는 형태이다.

 

 

 

컴포넌트에 스타일 입히기

import React from "react";

const styles = {
    wrapper: {
        margin: 8,
        padding: 8,
        display: "flex",
        flexDirection: "row",
        border: "1px solid grey",
        borderRadius: 16,
    },
    imageContainer: {},
    image : {
        width: 50,
        height: 50,
        borderRadius: 25,
    },
    contentContainer: {
        marginLeft: 8,
        display: "flex",
        flexDirection: "column",
        justifyContent: "center",
    },
    nameText: {
        color: "black",
        fontSize: 16,
        fontWeight: "bold",
    },
    commentText: {
        color: "black",
        fontSize: 16,
    },
};

function Comment(props) {
    return (
        <div style={styles.wrapper}>
            <div style={styles.imageContainer}>
                <img 
                    src="https://lh3.googleusercontent.com/proxy/fKYexLyW7D6DMKEsN_TZbTFFgn95uCZDwkBW8-YSORGtmw9KrzayhocMeyh__7sl0rW9XjR0Qlp2gC5-Txx9IXPzsKZxvdoXB9OCROAg4tzP_XBvrA"
                    style={styles.image} 
                />
            </div>

            <div style={styles.contentContainer}>
                <span style={styles.nameText}>김이박</span>
                <span style={styles.commentText}>
                    제가 쓴 첫 댓글
                </span>
            </div>
        </div>
    );
}

export default Comment;

 

다음과 같이 Comment.jsx를 수정한다. 

 

 

 

그럼 다음과 같이 댓글에 스타일이 적용된 것을 확인할 수 있다.

 

 

 

 

컴포넌트에 Props 추가하기

            <div style={styles.contentContainer}>
                <span style={styles.nameText}>{props.name}</span>
                <span style={styles.commentText}>
                    {props.comment}
                </span>
            </div>

 

우선 위에서 수정한 Comment 컴포넌트에서 닉네임과 댓글 부분을 다음과 같이 {props.name} 그리고 {props.comment}로 수정한다.

 

 

import React from "react";
import Comment from "./Comment";

function CommentList(props) {
    return (
        <div>
            <Comment name={"야야야"} comment={"hello world!"} />
            <Comment name={"좋아요"} comment={"ㅋㅋㅋㅋㅋㅋ"} />
        </div>
    );
}

export default CommentList;

 

CommentList 컴포넌트로 가서 Comment 컴포넌트들의 요소를 다음과 같이 설정하면...

 

올바르게 값들이 불려진 걸 확인할 수 있다.

 

 

 

Comment 데이터를 별도의 객체로 분리하기

import React from "react";
import Comment from "./Comment";

const comments = [
    {
        name: "손흥민",
        comment: "안녕하세요, 손흥민입니다.",
    },
    {
        name: "이강인",
        comment: "이강인입니다. 반갑습니다.",
    },
    {
        name: "김민재",
        comment: "제 이름은 김민재입니다. 반갑습니다.",
    },
];

function CommentList(props) {
    return (
        <div>
            {comments.map((comment) => {
                return (
                    <Comment name={comment.name} comment={comment.comment} />
                );
            })}
        </div>
    );
}

export default CommentList;

CommentList.jsx 에서 각 댓글 객체를 작성하고, 컴포넌트에서 map으로 각 댓글 객체 조회 후, Comment 컴포넌트 소환 후 각 요소들에 데이터들을 집어 넣는다.

 

 

댓글 객체의 데이터들이 불려져왔다.

'React' 카테고리의 다른 글

[React] Hooks  (0) 2024.08.06
[React] State and Lifecycle  (0) 2024.08.03
[React] Rendering Elements  (0) 2024.07.31
[React] JSX 의 장점과 사용법  (0) 2024.07.30
[React] create-react-app  (0) 2024.07.29

Elements 란?

어떤 물체를 구성하는 성분
리액트 앱을 구성하는 가장 작은 블록들

 

 

생김새

리액트 Elements는 자바스크립트 객체 형태로 존재
마음대로 생성되면 바꿀 수 없는 불변성

타입이 문자열일 경우

 

 

타입이 문자열이 아닐 경우

 

 

 

Element를 만드는 방식, type은 태그 이름, props가 속성, children이 자식 태그

 

 

 

 

Button Element가 ConfirmDialog Element에 속해 있다.

 

 

 

특징

불변성 - Elements 생성 후에는 children이나 attributes를 바꿀 수 없다!

 

 

 

렌더링하기

Root DOM Node

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


VirtureDOM에서 실제 DOM으로 랜더링되는 과정

const element = <h1>안녕, 리액트!</h1>;
ReactDOM.render(element, document.getElementById('root'));

 

 

 

실습 - 시계만들기

import React from "react";

function Clock(props) {
    return (
        <div>
            <h1>안녕, 리액트!!!!</h1>
            <h2>지금 시간 : {new Date().toLocaleTimeString()}</h2>
        </div>
    );
}

export default Clock;

 

다음과 같이 시계 엘레멘트를 만든다.

 

 

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import Clock from './chapter_04/Clock';

setInterval(() => {
  ReactDOM.render(
    <React.StrictMode>
    <Clock />
    </React.StrictMode>,
    document.getElementById('root')
  );
}, 1000);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

index.js로 가서 setInterval() 함수를 사용하여 1초간 시간을 갱신하게끔 한다.

 

 

 

터미널에서 npm start를 치면 브라우저가 열러서 시계가 작동되는 것을 확인할 수 있다.

'React' 카테고리의 다른 글

[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01
[React] JSX 의 장점과 사용법  (0) 2024.07.30
[React] create-react-app  (0) 2024.07.29
[React] React 란? & 연동하기  (0) 2024.07.29

JSX란?

자바스크립트(JS) 에 XML / HTML 기능을 추가한 것으로 A syntax extension to JavaScript (자바스크립트 확장 문법) 이라고 한다. 사실 JSX는 필수가 아니다. createElement() 라는 함수를 이용해서 구현을 할 수 있으나, 그래도 후술할 장점들 때문에 JSX가 많이 권장되는 편이다.

 

JSX 장점

- 간결한 코드

- 가독성 향상

- 버그 발견 쉬움

- Injection Attacks 해킹 방어

 

사용법

- 모든 자바스크립트 문법 사용 가능
- 태그의 속성에 값을 넣기 위해 큰 따옴표 사이에 문자열 넣거나
- 중괄호 사이에 자바스크립트 코드를 넣으면 됨!
- childeren 정의하는 법은 그냥 태그 안에 태그를 또 넣으면 됨

 

 

우선 지난 포스팅에서 create-react-app을 통해 만들어 놓은 애플리케이션 틀이 있을 것이다. 다음과 같이 파일과 폴더를 만든다.

 

 

import React from "react";

function Book(props) {
    return (
        <div>
            <h1>{`이 책의 이름은 ${props.name}입니다.`}</h1>
            <h2>{`이 책은 총 ${props.numOfPage}페이지로 이뤄져 있습니다.`}</h2>
        </div>
    );
}

export default Book;

Book.jsx

 

import React from "react";
import Book from "./Book";

function Library(props) {
    return (
        <div>
            <Book name="책이름 파이썬" numOfPage={300} />
            <Book name="책이름 AWS" numOfPage={400} />
            <Book name="책이름 리액트" numOfPage={500} />
        </div>
    );
}

export default Library;

Library.jsx

 

다음과 같이 Book 에 속한 태그들을 Library에서 설정한 것처럼 나열한다.

 

 

 

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import Library from './chapter_03/Library';

ReactDOM.render(
  <React.StrictMode>
    <Library />
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

index.js에 와서 chapter 폴더 속 Library.jsx를 불러와서 ReactDOM에 랜더링해서 화면에 보여주게 한다.

터미널에서 npm start를 치면 브라우저가 열리고 localhost:3000 주소로 페이지를 보여준다.

(단 주의해야 할 점이 터미널에서 npm start 명령어를 칠 경우 package-json 파일이 있는 폴더의 상위 페이지에서 입력해야 한다. 만약 다른 경로에 있을 경우 cd 명령어로 경로를 설정해주면 된다.)

 

 

랜더링한 화면을 볼 수 있다.

'React' 카테고리의 다른 글

[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01
[React] Rendering Elements  (0) 2024.07.31
[React] create-react-app  (0) 2024.07.29
[React] React 란? & 연동하기  (0) 2024.07.29

create-react-app

초기 환경을 설정해놓지 않고도, 리액트 프로젝트를 실행할 수 있도록 셋업을 완료해놓은 틀

 

 

터미널에 가서 리액트 애플리캐이션을 생성하기 위해 아래 처럼 명령어를 친다.

PS C:\Users\user\Documents\코리아IT\react> npx create-react-app my-app

뒤에 my-app은 내가 이름지은 프로젝트 명이다. 만약 프로젝트 명이 my-blog 라면 my-blog를 쓴다.

 

 

PS C:\Users\user\Documents\코리아IT\react> npm uninstall -g create-react-app

만약 안된다면 다음 명령어를 터미널에 입력 후, 다시 위의 명령어를 입력한다.

 

 

  cd my-app
  npm start

cd 명령어로 경로 변경 후 그리고 리액트 애플리케이션 실행을 위해 npm start를 치면

 

 

 

로컬호스트 3000 주소로 다음과 같은 창이 뜬다.

'React' 카테고리의 다른 글

[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01
[React] Rendering Elements  (0) 2024.07.31
[React] JSX 의 장점과 사용법  (0) 2024.07.30
[React] React 란? & 연동하기  (0) 2024.07.29

React 란??

메타에서 개발한 오픈소스 자바스크립트 라이브러리이다. 랜더링이 잦은 동적인 모던 웹에서 빠른 퍼포먼스를 낼 수 있도록 한다.

 

 

 

연동

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>내 블로그</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>내 블로그에 오신 분들 환영합니다.</h1>

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

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

 

우선 HTML에 다음과 같이 작성한다. root div 태그는 domContainer 역할을 한다. 리액트를 가져오고 리액트 컴포넌트를 가져온다.

 

 

 

// 리액트 컴포넌트
// 간단한 리액트의 함수 컴포넌트
function MyButton(props) {
    const [isClicked, setIsClicked] = React.useState(false);

    return React.createElement(
        'button',
        { onClick: () => setIsClicked(true) },
        isClicked ? 'Clicked!' : 'Click here!'
    )
}

// 리액트 컴포넌트를 DOM 컴포넌트에 랜더링, 컴포넌트를 화면에 보여지게 함
const domContainer = document.querySelector('#root');
ReactDOM.render(React.createElement(MyButton), domContainer);

 

자바스크립트로 작성한 리액트 컴포넌트이다. 간단하게 작성 후, DOM 컴포넌트에 랜더링해서 화면에 보여지게 할 것이다.

 

 

DOM 컴포넌트에 랜더링 하면 다음과 같은 버튼이 생기는데, 클릭하면 'Clicked!' 로 버튼 이름이 변한다.

'React' 카테고리의 다른 글

[React] State and Lifecycle  (0) 2024.08.03
[React] Components 와 Props  (0) 2024.08.01
[React] Rendering Elements  (0) 2024.07.31
[React] JSX 의 장점과 사용법  (0) 2024.07.30
[React] create-react-app  (0) 2024.07.29

+ Recent posts