๐Ÿ’ป My Work/๐Ÿ”ฅ React

[React/JS] ์š”์†Œ๊ฐ€ ๊ฐ์ฒด(Object)์ธ ๋ฐฐ์—ด(array) ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง / ํ•˜๋‚˜๋งŒ ์ถ”๊ฐ€, ์‚ญ์ œ, ์—…๋ฐ์ดํŠธ ๊ด€๋ฆฌํ•˜๊ธฐ

Jaeseo Kim 2022. 10. 31. 20:56

์œ„ ์˜ˆ์‹œ๋ฅผ ๊ตฌํ˜„ํ•ด๋ณผ๊ฒŒ์š”! โœจ

์šฐ์„ , ์ „์ฒด ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋ฐ‘์—์„œ ์„ค๋ช…์„ ๋ง๋ถ™์ด๋Š” ์‹์œผ๋กœ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!!

 

 

 

 

00. ์ „์ฒด ์ฝ”๋“œ


๋ช‡๋ช‡ ์ปดํฌ๋„ŒํŠธ๋Š” material design์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค๋Š” ์  ์œ ์˜ํ•ด ์ฃผ์„ธ์š”!

 

MainPage.js

import * as React from "react";
import { Grid, Button, Card, IconButton, Stack } from "@mui/material";
import ClearIcon from "@mui/icons-material/Clear";

export default function MainPage() {
  // ๋ฐฐ์—ด
  const [data, setData] = React.useState([]);

  /** ๊ฐ item update */
  function onChangeInput(event, index) {
    const target = event.target;

    let input = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    let result; // ๊ฒฐ๊ณผ๊ฐ’
    if (target.id === "name") {
      result = input.map((item, idx) =>
        idx === index ? { ...item, name: target.value } : { ...item }
      );
    } else if (target.id === "age") {
      result = input.map((item, idx) =>
        idx === index ? { ...item, age: target.value } : { ...item }
      );
    }
    setData(result); // ๊ฒฐ๊ณผ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ 
  }

  /** item ์ถ”๊ฐ€ */
  function addItem() {
    let tmp = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    /** ๋งจ ๋’ค์— ์ถ”๊ฐ€ */
    tmp.push({
      name: "",
      age: ""
    });
    setData(tmp); // ์ถ”๊ฐ€๋œ ๋ฐฐ์—ด๋กœ ๊ฐฑ์‹ 
  }

  /** item ์‚ญ์ œ */
  function removeItem(index) {
    let tmp = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    tmp.splice(index, 1); // ํ•ด๋‹นํ•˜๋Š” index ์š”์†Œ ์‚ญ์ œ
    setData(tmp); // ์‚ญ์ œ๋œ ๋ฐฐ์—ด๋กœ ๊ฐฑ์‹ 
  }

  return (
    <div className="App">
      <Grid container>
        <Stack sx={{ gap: "1.6rem" }}>
          {data.map((item, index) => (
            <Card key={index}>
              <Grid container sx={{ alignContent: "flex-start" }}>
                <Grid item xs>
                  <Grid container sx={{ alignItems: "center", gap: "1.6rem" }}>
                    <Grid item>
                      <h6>์ด๋ฆ„</h6>
                    </Grid>
                    <Grid item>
                      <input
                        id="name"
                        value={item.name}
                        onChange={(e) => onChangeInput(e, index)}
                      />
                    </Grid>
                  </Grid>
                  <Grid container sx={{ alignItems: "center", gap: "1.6rem" }}>
                    <Grid item>
                      <h6>๋‚˜์ด</h6>
                    </Grid>
                    <Grid item>
                      <input
                        id="age"
                        value={item.age}
                        onChange={(e) => onChangeInput(e, index)}
                      />
                    </Grid>
                  </Grid>
                </Grid>
                <Grid item>
                  <IconButton
                    aria-label="delete"
                    onClick={(e) => removeItem(index)}
                  >
                    <ClearIcon />
                  </IconButton>
                </Grid>
              </Grid>
            </Card>
          ))}
          <Grid container>
            <Button onClick={addItem} variant="contained">
              ์ถ”๊ฐ€
            </Button>
          </Grid>
        </Stack>
      </Grid>
    </div>
  );
}

 

 

 

 

01. ์š”์†Œ๊ฐ€ ๊ฐ์ฒด์ธ ๋ฐฐ์—ด


์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฐ์—ด๊ณผ

  // ๋ฐฐ์—ด
  const [data, setData] = React.useState([]);

 

๋ฐฐ์—ด์—๋Š”, ์•„๋ž˜์™€ ๊ฐ™์ด name, age๊ฐ€ key์ธ ๊ฐ์ฒด๋ฅผ ๋„ฃ๋Š”๋‹ค๊ณ  ํ• ๊ฒŒ์š”!

// ๊ฐ์ฒด(๋ฐฐ์—ด์˜ ์š”์†Œ)
{
  name: "",
  age: ""
}

 

 

 

 

02. ์š”์†Œ ์ถ”๊ฐ€


/** item ์ถ”๊ฐ€ */
  function addItem() {
    let tmp = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    /** ๋งจ ๋’ค์— ์ถ”๊ฐ€ */
    tmp.push({
      name: "",
      age: ""
    });
    setData(tmp); // ์ถ”๊ฐ€๋œ ๋ฐฐ์—ด๋กœ ๊ฐฑ์‹ 
  }
  
  
  return(
      ...
            <Button onClick={addItem} variant="contained">
              ์ถ”๊ฐ€
            </Button>
      ...
  )
1. ์ „๊ฐœ ์—ฐ์‚ฐ์ž( ... ) ๋กœ ํ˜„์žฌ data๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ด ์˜จ ํ›„
2. ๋ณต์‚ฌํ•ด์˜จ ๋ฐฐ์—ด์˜ ๋งจ ๋’ค์— ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
3. ์ด๋ ‡๊ฒŒ ์š”์†Œ๊ฐ€ ์ถ”๊ฐ€๋œ ๋ฐฐ์—ด๋กœ data๋ฐฐ์—ด์„ ๊ฐฑ์‹ ํ•ด์ค๋‹ˆ๋‹ค.

 

 

 

 

03. ์š”์†Œ ์—…๋ฐ์ดํŠธ


  /** ๊ฐ item update */
  function onChangeInput(event, index) {
    const target = event.target;

    let input = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    let result; // ๊ฒฐ๊ณผ๊ฐ’
    if (target.id === "name") {
      result = input.map((item, idx) =>
        idx === index ? { ...item, name: target.value } : { ...item }
      );
    } else if (target.id === "age") {
      result = input.map((item, idx) =>
        idx === index ? { ...item, age: target.value } : { ...item }
      );
    }
    setData(result); // ๊ฒฐ๊ณผ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ 
  }

  ...
  return(
	{data.map((item, index) => (
        ...
          /** ์ด๋ฆ„ input */
              <input
                id="name"
                value={item.name}
                onChange={(e) => onChangeInput(e, index)}
              />
        ...
          /** ๋‚˜์ด input */
            <input
                id="age"
                value={item.age}
                onChange={(e) => onChangeInput(e, index)}
              />
         ))}
     )

 

์ฃผ์˜ํ•ด์ฃผ์‹ค ์ !

1. map์„ ํ†ตํ•ด data ๊ฐ๊ฐ์˜ ์š”์†Œ๋“ค์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. -> item์€ { name: ์ด๋ฆ„๊ฐ’, age: ๋‚˜์ด๊ฐ’ } ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ฒ ์ฃ !
2. input์— id๋ฅผ ๋ถ€์—ฌํ•ด์ค๋‹ˆ๋‹ค. -> name๊ณผ age ๊ฐ๊ฐ์˜ onChange ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค. (๊ฐœ์ธ ์ทจํ–ฅ ๐Ÿ˜)
3. event.target์„ ์ž˜ ํ™œ์šฉํ•˜์—ฌ ๊ฐ index์— ๋งž๋Š” item์˜ name๊ณผ age์˜ ๊ฐ’์„ ์ž…๋ ฅ๊ฐ’๋Œ€๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ํ•จ์ˆ˜ onChangeInput๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค!

 

event.target์„ ์ฝ˜์†”๋กœ ์ฐ์€ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜„ํ•˜์‹ค ๋•Œ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!โ˜บ๏ธโ˜บ๏ธ

console.log(event.target);

 

 

 

 

04. ์š”์†Œ ์‚ญ์ œ


  /** item ์‚ญ์ œ */
  function removeItem(index) {
    let tmp = [...data]; // ํ˜„์žฌ data๋ฐฐ์—ด ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜๊ธฐ
    tmp.splice(index, 1); // ํ•ด๋‹นํ•˜๋Š” index ์š”์†Œ ์‚ญ์ œ
    setData(tmp); // ์‚ญ์ œ๋œ ๋ฐฐ์—ด๋กœ ๊ฐฑ์‹ 
  }
  
  return(
      ...
          <IconButton
            onClick={() => removeItem(index)}
          >
      ...
  )

 

1. ์ „๊ฐœ ์—ฐ์‚ฐ์ž( ... ) ๋กœ ํ˜„์žฌ data๋ฐฐ์—ด์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ด ์˜จ ํ›„
2. splice() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. 
3. ์ด๋ ‡๊ฒŒ ์š”์†Œ๊ฐ€ ์‚ญ์ œ๋œ ๋ฐฐ์—ด๋กœ data๋ฐฐ์—ด์„ ๊ฐฑ์‹ ํ•ด์ค๋‹ˆ๋‹ค.

 

 

 

 

 

โœจโœจโœจ๐Ÿคฉ๐Ÿคฉ๐Ÿคฉ