카테고리 없음

[새싹 금천 5기] 리액트 기본(2) (이노그리드_기업맟춤형 클라우드 인재 양성 캠프)

z00h 2025. 5. 20. 17:59

 

지난 포스팅에 이어 리액트 기본 문법 및 컴포넌트 구성, 상태관리에 대해 알아볼 예정이다.

 

📘 React 기본 문법 및 컴포넌트 구성

  1. 리액트 컴포넌트 구조 이해
  2. props를 활용한 컴포넌트 재사용

 

📗 React에서 상태 관리하기 (State)

  1. 클래스형 컴포넌트에서 상태(state) 관리
  2. 함수형 컴포넌트에서 상태 관리 (useState)

 

📙 이벤트 처리 및 입력값 제어

  1. 이벤트 핸들링 기초
  2. 입력값을 상태에 반영하기

 

 

MyClassComponent 각 컴퍼넌트의 이름, 나이를 전달해서 출력하도록 코드를 구현하였다.

(값을 고정시키지 않고 1개의 형식에서 다양한 출력이 가능하도록)

  1. App.jsx 에 값을 넘김 (부모 → 자식)에게 넘겨주는 props 변수

문자열인 경우 중괄호 생략 가능, 숫자는 중괄호로 표현

 

 

 

2. 자식이 값을 받음

render 함수 내 로그를 찍어주고 크롬 콘솔에서 로그 확인

 

 

 

3.  return 값 수정 {this.props.~}

  • {this.props.name}
  • {this.props.age}

 

 

 

4. props.name, props.age 를 비구조화를 통한 생략

 

 

 

 

 

MyFunctionComponent.jsx 파일을 생성해서 동일한 기능을 함수형 컴포넌트로 구현

객체가 매개변수로 넘어오기 때문에 비구조화시 중괄호를 꼭 써야한다.

매개변수명은 ‘props’가 아니여도 가능하다.

function MyFunctionComponent(props) {        //함수형은 props매개변수를 정의, 이름은 props로 꼭 안써도 됨
    console.log(props);
    const {name, age} = props
    return (
        <>
            <h1>이름은 {name}입니다.</h1>
            <h2>나이는 {age}살입니다.</h2>
        </>
    );
}

export default MyFunctionComponent;

 

 

 

App.jsx 파일에 MyFunctionComponent 컴포넌트를 추가

 

 

 

자식 컴포넌트에게 전달할 값을 별도 관리하도록 수정

App.jsx 수정

배열 데이터 생성 → map()함수를 이용해 N:N 방식으로 데이터를 생성하여 반환


 

import MyClassComponent from "./MyClassComponent";
import MyFunctionComponent from "./MyFunctionComponent";

const datas = [
    { name: "홍길동", age: 23 }, 
    { name: "고길동", age: 43 }, 
    { name: "신길동", age: 53 }, 
];

function App() {
    return (
        <>
            {
                datas.map(d => <MyClassComponent name={d.name} age={d.age} />)
            }
            <hr />
            {
                datas.map(d => <MyFunctionComponent name={d.name} age={d.age} />)
            }
        </>
    );
}
export default App;

 

 

**상태변수 (state)

컴포넌트 내부에서 읽고 업데이트 할 수 있는 값, 상태변경시 다시 랜더링이 일어남

  • 클래스형 컴포넌트 → setState() 메서드 사용하여 상태 변수 변경
  • 함수형 컴포넌트 → useState() 함수가 반환한 세터 함수를 사용하여 변경

 

  1. 클래스형 컴포넌트에서 상태변수 사용

Countet.jsx 파일 추가

import { Component } from "react";

class Counter extends Component {

state = {

count: 0

};

render() {

return (

<>

<h1>{this.state.count}</h1>

<button onClick={() => {

this.state.count = this.state.count + 1;

console.log(this.state.count);

}}>+1</button>

</>

);

}

}

export default Counter;

 

버튼을 누르면 변수의 값이 바뀌기 때문에 다시 출력되어야한다.

→ 즉 변수는 상태변수로 정의되어야 한다.

 

 

App.js 파일 내 Counter 컴포넌트 추가

클래스컴포넌트 내 setState 함수를 쓰지않고 count를 1씩 증가시켜보았다.

 

 

 

serState 함수를 쓰지않으면 화면에 반영되지 않음(콘솔에는 +1이 일어남)

 

 

 

serState 함수 사용시 화면에도 정상적으로 랜더링

 

 

 

2. 함수형 컴포넌트로 변경

Hook 함수인 useState함수 이용한다.

부모로부터 받을 값이 있을 경우 중괄호에 매개변수로 받음 (count, setCount)

 

 

 

이벤트 핸들러 함수를 외부로 추출시 plusOne() 함수로 setCount 호출

 

 

 

입력 이벤트 발생시 화면에 반영하고 버튼 클릭시 입력한 글자 띄우기

EventPractice.jsx 파일을 추가

import { useState } from "react";


const EventPractice = () => {
    const [message, setMessage] = useState("");
    const [name, setName] = useState("");
    
    const handleChangeMessage = e => setMessage(e.target.value); // onChange시 e.target.value를 통해 가져옴 (메세지 바뀌면 상태변수 반영)
    const handleChangeName = e => setName(e.target.value);
    const handleConform = () => alert(`메세지: ${message}\n 이름: ${name}`)


    return(
        <>
            <h1>이벤트 연습</h1>
            <input type="text" onChange={handleChangeMessage} value= {message} placeholder="메세지를 입력하세요."/>
            <input type="text" onChange={handleChangeName} value= {name} placeholder="이름을 입력하세요."/>

            <h2>메세지 : {message}</h2>
            <h2>이름 : {name}</h2>
            <button onClick={handleConform}>확인</button>
        </>
    );
};

export default EventPractice;

 

 

 

App.jsx 파일에 EventPractice 컴포넌트를 추가


import EventPractice from "./EventPractice";


function App() {
    return (
        <>          
            <EventPractice />
        </>
    );
}
export default App;

 

 

 

input 태그에 name 속성 추가하여 어디서 변경이 되었는지 특정한 후 →handleChange 메서드 1개로 통합 (e.target.name) 이용

import { useState } from "react";

const EventPractice = () => {
    const [message, setMessage] = useState("");
    const [name, setName] = useState("");

    const handleChange = e => {
        if (e.target.name === "message") {
            setMessage(e.target.value);
        } else if (e.target.name === "name") {
            setName(e.target.value);
        }
    };
    const handleConfirm = () => alert(`메시지: ${message}\n이름: ${name}`);

    return (
        <>
            <h1>이벤트 연습</h1>
            <input type="text" name="message" onChange={handleChange} value={message} placeholder="메시지를 입력하세요." />
            <input type="text" name="name" onChange={handleChange} value={name} placeholder="이름을 입력하세요." />

            <h2>메시지: {message}</h2>
            <h2>이름: {name}</h2>
            <button onClick={handleConfirm}>확인</button>
        </>
    );
};

export default EventPractice;

 

 

 

코드 재사용성을 높이기 위해 입력 데이터를 form객체에 묶어 할당한 코드

setFrom({...form, [e.target.name]: e.target.value}) : 기존 form 복사, 변경된 name 속성만 기존 form에서 덮어쓰기

Copy
import { useState } from "react";

const EventPractice = () => {
    // const [message, setMessage] = useState("");
    // const [name, setName] = useState("");

    // const handleChange = e => {
    //     if (e.target.name === "message") {
    //         setMessage(e.target.value);
    //     } else if (e.target.name === "name") {
    //         setName(e.target.value);
    //     }
    // };
    
    const [form, setFrom] = useState({
        message:'',
        name:''
    });
    
    const handleChange = e => setFrom({...form, [e.target.name]: e.target.value}); // name 속성의 변경된값만 form에서 업데이트
    const {message, name} = form; //비구조화

    const handleConfirm = () => alert(`메시지: ${message}\n이름: ${name}`);

    return (
        <>
            <h1>이벤트 연습</h1>
            <input type="text" name="message" onChange={handleChange} value={message} placeholder="메시지를 입력하세요." />
            <input type="text" name="name" onChange={handleChange} value={name} placeholder="이름을 입력하세요." />

            <h2>메시지: {message}</h2>
            <h2>이름: {name}</h2>
            <button onClick={handleConfirm}>확인</button>
        </>
    );
};

export default EventPractice;