React 리스트(List)와 키(Key)

CDH·2025년 5월 13일

개념

리스트

  • 같은 아이템을 순서대로 모아놓은 것
  • 자료구조
    - 배열 : 자바스크립트의 변수나 객체를 하나의 변수로 묶어놓은 것

  • 각 객체나 아이템을 구분하는 고유한 값
  • 리액트에서는 배열과 키를 사용하여 반복되는 다수의 엘리먼트를 쉽게 렌더링 가능


Array.map( ) 활용하여 여러개의 컴포넌트 랜더링

  • 배열에 모든 요소에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환.
 const numbers = [1, 2, 3, 4, 5];
 const listItems = numbers.map(number =>
 	<li>{number}</li>
 );


리스트 출력하기

NumberList.jsx

import React from "react";

export default function NumberList(props) {
    const {numbers } = props;

    const listItems = numbers.map( number =>
        <li> {number} </li>
    );


return (
    <ul> {listItems}</ul>
);

}

index.js

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

import reportWebVitals from './reportWebVitals';

import NumberList from './components/NumberList';

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <NumberList numbers = { [1,2,3,4,5] } />
  </React.StrictMode>
);

reportWebVitals();


리스트에서 키

• 리스트에서 아이템을 구분하기 위한 고유한 값 (중복 X)
• 리스트에서 어떤 아이템이 변경, 추가 또는 제거되었는지 구분하기 위해 사용
• 키의값은 같은 List에 있는 Element 사이에서만 고유한 값이면 됨


실습

  • 리스트와 키를 사용한 출석부 컴포넌트 제작
import React from "react";

const students = [
    {
        id: 1,
        name: "Inje",
    },
    {
        id: 2,
        name : "Steave",
    },
    {
        id:3, 
        name: "Bill"
    },
    {
        id: 4,
        name: "Jeff",
    }
];

export default function AttendanceBook(props) {
    return (
        <ul>
            {students.map((student, index) => {
                return <li key={student.id}>{student.name}</li>
            })}
        </ul>
    );
}


폼(Forms)

  • 폼(Forms)
    - 사용자로부터 입력을 받기 위해 사용하는 양식

    • 리액트와 HTML 폼의 차이
      • 리액트는 컴포넌트 내부에서 state를 통해 데이터를 관리
      • HTML 폼은 엘리먼트 내부에 각각의 state가 존재


HTML Form


제어 컴포넌트(Controlled Component)

  • React에 의해서 값이 제어되는 컴포넌트 (input form element)

  • 제어 컴포넌트를 사용하면 입력값이 리액트 컴포넌트의 state를 통해 관리할 수 있음

  • 사용자의 입력을 직접적으로 제어할 수 있음
    - 입력 양식의 초기값을 원하는대로 지정
    - 어떤 양식의 값이 변경되었을 때 다른 양식의 값을 자동으로 변경할 수 있음

예시


textarea 태그


select 태그

여러 개의 입력 처리


Input Null Value

  • 제어 컴포넌트에서 value 값을 지정하되 입력값을 자유롭게 변경하고자 할 때
    - 제어 컴포넌트에 value 값이 정해지면 입력값을 바꿀 수 없음
    - value에 undefined 또는 null을 넣어 주면 입력이 가능한 상태로 변경할 수 있음

실습코드

import React, {useState} from 'react';

export default function Reservation(props) {
    const [haveBreakFast, setHaveBreakFast] = useState(true);
    const [numberOfGeust, setNumberOfGeust] = useState(2);

    const handleSubmit = (event) => {
        alert(`아침식사 여부: ${haveBreakFast}, 방문객수: ${numberOfGeust}`);
        event.preventDefault();
    }

    return (
        <form onSubmit={handleSubmit}>
            <input value={null} /> <br /> {/* 값이 있다면 키보드 입력 안 됨 */}
            <label>
                아침식사:
                <input type = "checkbox"
                    checked = {haveBreakFast}
                    onChange = {(event) => {
                        setHaveBreakFast(event.target.checked);
                    }}
                />
            </label>
                <br />
            <label>
                방문객수 : 
                <input type = 'number'
                    value = {numberOfGeust}
                    onChange={(event) => {
                        setNumberOfGeust(event.target.value);
                    }}
                />
            </label>
            <button type='submit'>제출</button>
        </form>
    )
}

실습. 사용자 정보입력

  • 사용자의 정보를 입력받는 가입 양식 컴포넌트

import React, { useState } from "react";

export default function SignUp(props) {
    const [name, setName] = useState("");
    const [gender, setGender] = useState("남자");
    const [email, setEmail] = useState("");
    const [emailError, setEmailError] = useState("");
    const [password, setPassword] = useState("");
    const [birthdate, setBirthdate] = useState('');
    const [agree, setAgree] = useState(false);
    
    const handleChangeName = (event) => {
        setName(event.target.value);
    };

    const handleChangeGender = (event) => {
        setGender(event.target.value);
    };

    const handleSubmit = (event) => {
        event.preventDefault();
        if (!agree) {
            alert('약관 동의가 필요합니다');
            return;
        }
        if (!emailError) {
            alert(`이름: ${name} \n성별: ${gender} \n이메일: ${email} \n생년월일: ${birthdate}`);
        }
    };

    const handleEmailChange = (event) => { // 이메일 검증
        const value = event.target.value;
        setEmail(value);

        const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        
    };


    return (
        <form onSubmit={handleSubmit}>
            <label>
                이름:
                <input type="text" value={name}
                    onChange={handleChangeName} />
            </label>
                <br />
            <label>
                성별: 
                <select value={gender}
                    onChange={handleChangeGender}>
                    <option value="남자">남자</option>
                    <option value="여자">여자</option>
                </select>
            </label>
                <br />
            <label>
                이메일 : 
                <input type="email" value={email}
                    onChange={handleEmailChange} />
            </label>
                <br />
            <label>
                비밀번호 : 
                <input type="password" value={password}
                    onChange={ (e) => setPassword(e.target.value)} />
            </label>
                <br />
            <label>
                생년월일 : 
                <input type='date' value={birthdate} onChange={ (e) => setBirthdate(e.target.value)} />
            </label>
            {emailError && (
                <p className="text-red-500 text-sm mb-2">{emailError}</p>
            )}
                <br />
            <label>
                <input type = "checkbox"
                    checked = {agree}
                    onChange = {(event) => {
                        setAgree(event.target.checked);
                    }}
                />
                [필수] 약관에 동의합니다
            </label>
                <br />
            <button type="submit">가입</button>
        </form>
    );
}

0개의 댓글