์›น ๊ฐœ๋ฐœ/React.js

React(13) - UserList ๋งŒ๋“ค๊ธฐ ๋ฏธ๋‹ˆ ์›น ๋งŒ๋“ค๊ธฐ

SolartheNomad 2023. 6. 2. 01:43

๐ŸŒˆ AddUser.js

import React from "react";
import Card from '../UI/Card';
import classes from './AddUser.module.css';
import Button from './UI/Button';
import {useState} from 'react';
import ErrorModal from "../UI/ErrorModal";

const AddUser = props =>{
    const [enteredUsername, setEnteredUsername] = useState('');

    const [enteredAge, setEnteredAge] =useState('');
    const [error, setError] = useState();

    const addUserHandler =(event) =>{
        event.preventDefault();
        
        //trim() : ์•ž ๋’ค ๊ณต๋ฐฑ ์ œ๊ฑฐ(์œ ํšจ์„ฑ ๊ฒ€์‚ฌ)
        if(enteredUsername.trim().length ===0 || enteredAge.trim().length ===0) {
            setError({
                title : 'Invalid input',
                message : 'Please enter a valid name and age'
            })
            return ;
        }
        if(+enteredAge < 1) {
            setError({
                title : 'Invalid input',
                message : 'Please enter a valid name and age'});
            return ;
        }
 
    
    
    //์ดˆ๊ธฐํ™” ๋กœ์ง
        props.onAddUser(enteredUsername, enteredAge);
        console.log(enteredUsername + ' ' + enteredAge)
        setEnteredUsername('');
        setEnteredAge('');
    };

    const usernameChangeHandler = (event) =>{
        setEnteredUsername(event.target.value);

    }

    const ageChangeHandler=(event)=>{
        setEnteredAge(event.target.value);
    }

    const errorHandler =() =>{
        setError(null);
    }

   return(
    <div>{error && <ErrorModal title={error.title} message={error.message }
    onConfirm={errorHandler}/>}
    <Card className={classes.input}>
           <form onSubmit={addUserHandler}>
               <label htmlFor="username">Username</label>
               <input id="username" value={enteredUsername} type="text" onChange={enteredUsername} />
               <label htmlFor="userage">Age(Years)</label>
               <input id="userage" value={ageChangeHandler} type="text" onChange={enteredAge} />
               <Button type="submit">Add User</Button>
           </form>

       </Card></div>
   );
};

export default AddUser;

 

 

๐ŸŒธ ํ•„์š”ํ•œ ๋ชจ๋“ˆ ์ž„ํฌํŠธํ•ด์˜ค๊ธฐ 

import React from "react";
import Card from '../UI/Card'; // Card ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ชผ๊ฐœ๋†“์•˜๊ณ , UI ๋ชจ๋“ˆ์€ ์žฌ์‚ฌ์šฉ์„ ์œ„ํ•œ ์ปดํฌ๋„ŒํŠธ์ด๋‹ค. 
import classes from './AddUser.module.css';
import Button from './UI/Button';
import { useState } from 'react';
import ErrorModal from "../UI/ErrorModal"; //์—๋Ÿฌ๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ชจ๋‹ฌ์ฐฝ ๊ฐ€์ ธ์˜ค๊ธฐ

 

๐ŸŒธ ์ดˆ๊ธฐ๊ฐ’, ์—…๋ฐ์ดํŠธ ์„ค์ • = useState

- ํ˜•ํƒœ : const [๋ณ€์ˆ˜, ๋ณ€์ˆ˜๋ณ€๊ฒฝํ•จ์ˆ˜] = useState('๋ณ€์ˆ˜ ์•ˆ์— ์„ค์ •๋˜๋Š” ์ดˆ๊ธฐ๊ฐ’');

  // enteredUsername, enteredAge๋Š” ๊ฐ๊ฐ input์— ๋„ฃ์–ด์ง€๋Š” ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„๊ณผ ๋‚˜์ด๋ฅผ ์˜๋ฏธํ•จ. ์ด๋•Œ ์‚ฌ์šฉ์ž์˜ ๋‚˜์ด์™€ ์ด๋ฆ„์€ update๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ, ์ดˆ๊ธฐ๊ฐ’ ์„ค์ • ๋ฐ ๋ณ€๊ฒฝ์„ ์œ„ํ•˜์—ฌ useState๋กœ ๊ด€๋ฆฌํ•œ๋‹ค. 
  // error ๋ฉ”์„ธ์ง€๊ฐ€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ถœ๋ ฅ ๋ฉ”์„ธ์ง€ ๊ฐ’๊ณผ ํƒ€์ดํ‹€์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ์—ญ์‹œ useState๋กœ ๊ด€๋ฆฌํ•œ๋‹ค.
  
  const [enteredUsername, setEnteredUsername] = useState('');
  const [enteredAge, setEnteredAge] = useState('');
  const [error, setError] = useState();

 

๐Ÿ’ ํ™”๋ฉด์— ์ถœ๋ ฅ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ ์ž‘์„ฑํ•˜๊ธฐ

return(
    <div>{error && <ErrorModal title={error.title} message={error.message} onConfirm={errorHandler} />}
    <Card className={classes.input}>
           <form onSubmit={addUserHandler}>
               <label htmlFor="username">Username</label>
               <input id="username" value={enteredUsername} type="text" onChange={enteredUsername} />
               <label htmlFor="userage">Age(Years)</label>
               <input id="userage" value={ageChangeHandler} type="text" onChange={enteredAge} />
               <Button type="submit">Add User</Button>
           </form>

       </Card></div>
   );

 

๐Ÿ’ error ๋ชจ๋‹ฌ์ฐฝ ์ถœ๋ ฅ ์ •์˜

{error && <ErrorModal title={error.title} message={error.message} onConfirm={errorHandler} />}

- {error && ...}์€ error๊ฐ€ truthy ๊ฐ’์ผ ๋•Œ๋งŒ ๊ทธ ์ดํ›„์˜ ํ‘œํ˜„์‹์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ์ฆ‰, &&์˜ ์˜๋ฏธ๋Š” && ์•ž์— ๋ถ™์€ ๋ถ€๋ถ„์ด ์ฐธ์ธ ๊ฒฝ์šฐ์— ๋‹ค์Œ์˜๊ฒฐ๊ณผ ๊ฐ’์„ ๋„์ถœํ•  ์ˆ˜ ์žˆ๋Š” , if true๊ฐ€ ๋œ๋‹ค. 

- onConfirm์€ ๋‚ด์žฅ๋œ ํŠน์„ฑ์ด ์•„๋‹Œ, ๋งŒ๋“ค์–ด๋‚ธ ํŠน์„ฑ์ด๋‹ค. ๋”ฐ๋ผ์„œ onConfirm์„ ์ •์˜ํ•ด์ฃผ์–ด์•ผ ๋˜๋Š”๋ฐ onConfirm์€  errorHandlerํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ์ž‘์„ฑ๋œ ์†์„ฑ์ด๋‹ค. (AddUser.js์—์„œ ๋งŒ๋“ค์–ด๋‚ธ ์†์„ฑ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋จ) error ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋ฉด ErrorModal ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ•˜๊ณ , ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์•„๋ฌด๊ฒƒ๋„ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰ ์•„๋ž˜์—์„œ ErrorModal.js์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•˜๊ฒ ์ง€๋งŒ, 

 

 

๐Ÿ’ input ํƒœ๊ทธ์˜ ์ƒํƒœ๊ด€๋ฆฌ 

               <input id="username" value={enteredUsername} type="text" onChange={usernameChangeHandler} />
               <label htmlFor="userage">Age(Years)</label>
               <input id="userage" value={enteredUserage} type="text" onChange={ageChangeHandler} />
               <Button type="submit">Add User</Button>

 

 

๐Ÿ’ addUserHandler

- ํผ์˜ submit ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ ํ›„์— ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค. ์ด๋•Œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋Š” ์•„๋ž˜์˜ if ์กฐ๊ฑด๋ฌธ๋“ค์ด๋‹ค.

- ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ์— ์‹คํŒจํ•˜๋ฉด setError ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ์„ค์ •(errorModal ๋ฌธ๊ตฌ๋ฅผ ์ž‘์„ฑํ•จ)

  const addUserHandler = (event) => {
    event.preventDefault();
// trim() : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋‚ด์žฅํ•จ์ˆ˜๋กœ์„œ, ๋ฌธ์ž์—ด์˜ ์•ž๊ณผ ๋’ค์˜ ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•ด์ค€๋‹ค. 
// || : and์™€ ๊ฐ™์Œ 
    if (enteredUsername.trim().length === 0 || enteredAge.trim().length === 0) {
      setError({
        title: 'Invalid input',
        message: 'Please enter a valid name and age'
      });
      return;
    }
    if (+enteredAge < 1) {
      setError({
        title: 'Invalid input',
        message: 'Please enter a valid name and age'
      });
      return;
    }

    props.onAddUser(enteredUsername, enteredAge);
    console.log(enteredUsername + ' ' + enteredAge)
    setEnteredUsername('');
    setEnteredAge('');
  };

 

๐Ÿญ event.preventDefault();   

- addUserHandler ํ•จ์ˆ˜์—์„œ ํผ์˜ submit ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „์— ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ํผ์ด ์ œ์ถœ๋  ๋•Œ ํŽ˜์ด์ง€๊ฐ€ ๋‹ค์‹œ ๋กœ๋“œ๋˜๋Š” ๋™์ž‘์„ ๋ง‰๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ๋™์ž‘์ธ ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์ฃผ๋กœ form ํƒœ๊ทธ์˜ submit ์†์„ฑ์ด ๋ถ™๊ฒŒ ๋  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. 

 

๐Ÿญ props.onAddUser(enteredUsername, enteredAge)

- props ๊ฐ์ฒด๋กœ ์ „๋‹ฌ๋œ onAddUser ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. 

- enteredUsername๊ณผ enteredAge๋Š” ํ˜„์žฌ ์ž…๋ ฅ๋œ ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋‚˜์ด๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์ด ๊ฐ’์„ onAddUser ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ onAddUser์€ props์— ์ข…์†๋œ ํ•จ์ˆ˜ ๊ฐ์ฒด์ด๋ฉฐ, ์ด๊ฒƒ์„ addUserHandler์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰ ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์—์„œ (AddUser.js๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ) ์ด ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์•ผ ํ•จ

- enteredUsername, entereAge๋Š” input value์— ์ž‘์„ฑ๋œ ์ž…๋ ฅ๋ณ€์ˆ˜๋“ค์ด๊ณ  ์ด ์นœ๊ตฌ๋“ค์„ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์™€์„œ onAddUserํ•จ์ˆ˜์—์„œ ์ฒ˜๋ฆฌํ•จ. 

 

๐Ÿญ setEnteredUsername(''); setEnteredAge('');

- ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ถ€๋ถ„

- enteredUsername ์ƒํƒœ๋ฅผ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์„ค์ •ํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ช… ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ๋น„์šฐ๊ณ , setEnteredAge('')๋Š” enteredAge ์ƒํƒœ๋ฅผ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์„ค์ •ํ•˜์—ฌ ๋‚˜์ด ์ž…๋ ฅ ํ•„๋“œ๋ฅผ ๋น„์šฐ๊ฒŒ ๋˜์–ด ๋‹ค์Œ ์‚ฌ์šฉ์ž๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. 

 

- +enteredAge๋Š” enteredAge ๋ณ€์ˆ˜๋ฅผ ์ˆซ์ž๋กœ ํ˜•๋ณ€ํ™˜ํ•˜๋Š” ๋ถ€๋ถ„์œผ๋กœ, enteredAge๋Š” ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ž…๋ ฅ๋œ ๋‚˜์ด ๊ฐ’์ด๊ธฐ ๋•Œ๋ฌธ์—, + ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆซ์ž๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•œ๋‹ค. 

 

๐Ÿ“™ UI

 

๐ŸŒˆ ErrorModal.js

import React from "react";
import Card from './Card';
import Button from './Button';
import classes from './ErrorModal.module.css';

const ErrorModal = props =>{
    return (
        <div>
            <div className={classes.backdrop} onClick={props.onConfirm}></div>
        <Card className={classes.modal}>
            <header className={classes.header}>
                <h2>{props.title}</h2>
            </header>
            <div className={classes.content}>
                <p>{props.message}</p>
            </div>
            <fotter className={classes.action}>
                <Button onClick={props.onConfirm}>Okay</Button>

            </fotter>

        </Card>
        </div>

    );
};


export default ErrorModal;

- ์‚ฌ์‹ค... ErrorModal ์ปดํฌ๋„ŒํŠธ์— ๋Œ€ํ•ด์„œ ์„ค๋ช…ํ•  ๊ฒƒ์€ ๋”ฑํžˆ ์—†๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ css.Module ํ˜•ํƒœ๋กœ ํ”„๋กœ๋•ํŠธ ๊ด€๋ฆฌ๋ฅผ ์ž˜ํ•˜์ง€๋„ ์•Š๊ธฐ๋„ ํ•˜๊ณ , ๋ณดํ†ต ์Šคํƒ€์ผ์ปดํฌ๋„ŒํŠธ, StoryBook, Antd, Reactstrap ๋“ฑ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ถˆ๋Ÿฌ์™€์„œ css styling์„ ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๊ธฐ ๋•Œ๋ฌธ์— classes.action ,clsses.header ๋“ฑ์˜ ์„ค๋ช…์„ ์ž์„ธํ•˜๊ฒŒ ๋‹ค๋ฃจ์ง€๋Š” ์•Š๋„๋ก ํ•œ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•˜์ž๋ฉด,  Error.cssํŒŒ์ผ์˜ ์ด๋ฆ„์„ Error.module.css๋กœ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์ค€๋‹ค์Œ์—,  ์—ฌ๊ธฐ์„œ . ๋“ฑ์œผ๋กœ ์ •์˜๋œ ์Šคํƒ€์ผ๋ง์˜ ์ด๋ฆ„์„ ๋ถ™์—ฌ html ํƒœ๊ทธ์˜ className = {classes.์Šคํƒ€์ผ๋ง์ด๋ฆ„}์œผ๋กœ className์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

- backdrop: ๋ฐฐ๊ฒฝ์„ ๋ถˆํˆฌ๋ช…ํ•˜๊ฒŒ ๊ฐ€๋ฆฌ๋Š” ์—ญํ• ์„ ํ•˜๋Š” div ์š”์†Œ์ด๋ฉฐ ๋ชจ๋‹ฌ ์ฐฝ ์™ธ๋ถ€๋ฅผ ํด๋ฆญํ•˜๋ฉด props.onConfirm ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค.

- Button: ํ™•์ธ ๋ฒ„ํŠผ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋ฉฐ  props.onConfirm ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ๋‹ค. 

 

๐ŸŒˆ Card.js

import React from "react";
import classes from './Card.module.css';

const Card = props =>{
    //Card.module.css์˜ card๊ฐ€์ ธ์˜ค๊ณ  ๊ฑฐ๊ธฐ์— ์žˆ๋Š” css styling์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜๋ฏธ
    return <div className={`${classes.card} ${props.className}`}>{props.children}</div>
};

export default Card;

- ์—ฌ๊ธฐ์„œ๋„ ๋”ฑํžˆ ๋ณผ๊ฑด ์—†์ง€๋งŒ..... ${classes.card} ${props.className}์„ ์‚ฌ์šฉํ•˜์—ฌ Card.module.css ํŒŒ์ผ์—์„œ ์ •์˜๋œ card ํด๋ž˜์Šค์™€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ „๋‹ฌ๋œ className ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ํด๋ž˜์Šค๋ฅผ ์ ์šฉํ•ด์ค€๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ๋ง์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

- props.children: ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ Card ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋œ ์ž์‹ ์š”์†Œ๋“ค์„ ๋ Œ๋”๋งํ•ด์ค€๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Card ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ํฌํ•จ๋œ ๋‚ด์šฉ์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐ŸŒˆ Button.js

import React from "react";

import classes from './Button.module.css';

const Button =props =>{
    return <button className = {classes.button} type = {props.type || 'button'} onClick = {props.onClick}>{props.children}</button>
}

- ์œ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ props๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„์˜ค๊ณ  ์žˆ์Œ : ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ์†์„ฑ์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ 

- type ์†์„ฑ: props.type์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฒ„ํŠผ์˜ ํƒ€์ž…์„ ์ง€์ •ํ•ด์ค€๋‹ค. props.type์ด ์ฃผ์–ด์ง€์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ 'button'์„ ์‚ฌ์šฉํ•œ๋‹ค.  <Button type="submit">Add User</Button>์—์„œ์˜ ํƒ€์ž…์„ ๋ฐ›์•„์˜ค๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด ๊ทธ ์˜ˆ์‹œ์ž„

- onClick ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ: props.onClick์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ฆญ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ฒ„ํŠผ ํด๋ฆญ์— ๋Œ€ํ•œ ๋™์ž‘์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

๐ŸŒˆ UserList.js

- props๋ผ๋Š” ๊ฐ์ฒด์˜ users ์†์„ฑ์— ์žˆ๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๋ถ€๋ถ„์ž„. ์ด๋•Œ props๋Š” App.js๋ฅผ ์˜๋ฏธํ•œ๋‹ค. App.js์—์„œ UserList.js๋ฅผ ์ž„ํฌํŠธํ•ด์˜ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

- users ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ์— ๋Œ€ํ•ด ๋ฐ˜๋ณตํ•˜๋ฉฐ, ๋ฐฐ์—ด์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ›์•„์™€์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ, user ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ˜„์žฌ ๋ฐ˜๋ณต ์ค‘์ธ users ๋ฐฐ์—ด ์š”์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฒƒ์ด๋‹ค.  

- props.๋ฐฐ์—ด์ด๋ฆ„.map((๋ฐฐ์—ด์š”์†Œ์ด๋ฆ„ : ์•„๋ฌด๊ฑฐ๋‚˜ ํ•˜๋Š”๋ฐ, ๋ณดํ†ต users, elements์ด๋ฏ€๋กœ element๋ผ๊ณ  ํ•จ) => (์ถœ๋ ฅํ˜•ํƒœ : {๋ฐฐ์—ด์š”์†Œ์ด๋ฆ„.์†์„ฑ1} {๋ฐฐ์—ด์š”์†Œ์ด๋ฆ„.์†์„ฑ2}...))

import React from "react";
import Card from "../UI/Card";
import classes from './UserList.module.css';



const UsersList = props =>{

    return (
        <Card className = {classes.users}>
        <ul>
            
            {props.users.map((user) =>( <li key={user.id}>{user.name} ({user.age} years old)</li>))}
            
        </ul>
        </Card>

    );
};

export default UsersList;

- {user.name}์€ user ๊ฐ์ฒด์˜ name ์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ์ด๋ฆ„์„ ์ถœ๋ ฅํ•œ๋‹ค.

- {user.age}๋Š” user ๊ฐ์ฒด์˜ age ์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์‚ฌ์šฉ์ž์˜ ๋‚˜์ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

- ์ฆ‰ ๋ฐฐ์—ด ์š”์†Œ์˜ ์ถœ๋ ฅ ํ˜•ํƒœ๋Š” {๋ฐฐ์—ด์˜ ์š”์†Œ.์†์„ฑ}   ์ด ํ˜•ํƒœ๋กœ ์ถœ๋ ฅํ•ด์•ผ ํ™”๋ฉด์—์„œ ์ถœ๋ ฅ๋œ๋‹ค. 

-  <li key={user.id}></li> : key ์†์„ฑ์€ React์—์„œ ๋ฆฌ์ŠคํŠธ ํ•ญ๋ชฉ์„ ๋ Œ๋”๋งํ•  ๋•Œ ํ•„์š”ํ•œ ๊ณ ์œ  ์‹๋ณ„์ž์ด๋‹ค. ๋ฐ˜๋“œ์‹œ json ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ ์ž‘์„ฑํ•ด์ค˜์•ผ ์˜ค๋ฅ˜๊ฐ€ ๋œจ์ง€ ์•Š๋Š”๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” user.id ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ ํ•ญ๋ชฉ์„ ๊ตฌ๋ณ„ํ•œ๋‹ค. 

 

 

App.js

import React from 'react';
import AddUser from './components/Users/AddUser';
import UsersList from './components/Users/UsersList';
import {useState} from 'react';

const App=() =>{
    const [usersList, setUsersList] = useState([]);

    const addUserHandler = (userName, userAge) =>{
        setUsersList((prevUserlist)=>{
            return [...prevUserlist, {name : userName, age : userAge, id : Math.random().toString()}];
        });

    }
    return (
        <div>
            <AddUser onAddUser={addUserHandler} />
            <UsersList users={usersList}/>

        </div>
    )

}

export default App;