๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
ํ”„๋ก ํŠธ์—”๋“œ/React

๋ฆฌ์•กํŠธ์˜ ๋ฐฐ์—ด

by alswlfl 2022. 11. 17.

๋ฐฐ์—ด์— ํ•ญ๋ชฉ ์ถ”๊ฐ€

: ๋ฐฐ์—ด์— ๋ณ€ํ™”๋ฅผ ์ค„ ๋•Œ, ๊ฐ์ฒด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ถˆ๋ณ€์„ฑ์„ ์ง€์ผœ์ฃผ์–ด์•ผ ํ•จ

โžฃ ๊ธฐ์กด์˜ ๋ฐฐ์—ด์„ ํ•œ ๋ฒˆ ๋ณต์‚ฌํ•˜๊ณ  ๋‚˜์„œ ์‚ฌ์šฉ

 

App์ปดํฌ๋„ŒํŠธ์—์„œ ์ƒํƒœ๊ด€๋ฆฌํ•˜๊ณ , CreateUser์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” input๊ฐ’ ๋ฐ ์ด๋ฒคํŠธ๋กœ ๋“ฑ๋กํ•  ํ•จ์ˆ˜๋“ค์„ props๋กœ ๋„˜๊ฒจ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ

import React from "react";

function CreateUser({ username, email, onChange, onCreate }) {
  return (
    <div>
      <input
        name="username"
        placeholder="๊ณ„์ •๋ช…"
        onChange={onChange}
        value={username}
      />
      <input
        name="email"
        placeholder="์ด๋ฉ”์ผ"
        onChange={onChange}
        value={email}
      />

      <button onClick={onCreate}>๋“ฑ๋ก</button>
    </div>
  );
}

export default CreateUser;

1. spread ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ

import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;
  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ]);

  const nextId = useRef(4); //useRef() ์‚ฌ์šฉํ•  ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋„ฃ์–ด์ฃผ๋ฉด, ์ด ๊ฐ’์ด .current๊ฐ’์˜ ๊ธฐ๋ณธ๊ฐ’์ด ๋จ
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    setUsers([...users, user]);  //spread ์‚ฌ์šฉ
    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1; //๊ฐ’ ์ˆ˜์ • ์‹œ, .current ๊ฐ’ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ณ , ์กฐํšŒํ•  ๋•Œ๋„ .current์กฐํšŒํ•˜๋ฉด ๋จ
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} />
    </>
  );
}

export default App;

2. concatํ•จ์ˆ˜ ์‚ฌ์šฉ

concatํ•จ์ˆ˜: ๊ธฐ์กด์˜ ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ , ์ƒˆ๋กœ์šด ์›์†Œ๊ฐ€ ์ถ”๊ฐ€๋œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์คŒ

import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;
  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ]);

  const nextId = useRef(4); //useRef() ์‚ฌ์šฉํ•  ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋„ฃ์–ด์ฃผ๋ฉด, ์ด ๊ฐ’์ด .current๊ฐ’์˜ ๊ธฐ๋ณธ๊ฐ’์ด ๋จ
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    setUsers(users.concat(user));  //concatํ•จ์ˆ˜ ์ด์šฉ
    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1; //๊ฐ’ ์ˆ˜์ • ์‹œ, .current ๊ฐ’ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ณ , ์กฐํšŒํ•  ๋•Œ๋„ .current์กฐํšŒํ•˜๋ฉด ๋จ
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} />
    </>
  );
}

export default App;

 

๋ฐฐ์—ด์— ํ•ญ๋ชฉ ์ œ๊ฑฐ

import React from "react";

function User({ user, onRemove }) {
	//์‚ญ์ œ ๋ฒ„ํŠผ์ด ํด๋ฆญ๋  ๋•Œ user.id๊ฐ’์„ props๋กœ ๋ฐ›์•„์˜ฌ onRemoveํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„ฃ์–ด ํ˜ธ์ถœ
   	//onRemove๋Š” id๊ฐ€ _์ธ ๊ฐ์ฒด ์‚ญ์ œ
  return (
    <div>
      <b>{user.username}</b> <span>({user.email})</span>
      <button onClick={() => onRemove(user.id)}>์‚ญ์ œ</button> 
    </div>
  );
}

function UserList({ users, onRemove }) {
  return (
    <div>
      {users.map((user) => (
        <User user={user} key={user.id} onRemove={onRemove} />
      ))}
    </div>
  );
}

export default UserList;
import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;
  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
    },
  ]);

  const nextId = useRef(4); //useRef() ์‚ฌ์šฉํ•  ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋„ฃ์–ด์ฃผ๋ฉด, ์ด ๊ฐ’์ด .current๊ฐ’์˜ ๊ธฐ๋ณธ๊ฐ’์ด ๋จ
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    setUsers(users.concat(user));
    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1; //๊ฐ’ ์ˆ˜์ • ์‹œ, .current ๊ฐ’ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ณ , ์กฐํšŒํ•  ๋•Œ๋„ .current์กฐํšŒํ•˜๋ฉด ๋จ
  };

  const onRemove = (id) => {
    //user.id๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฆ
    //=user.id๊ฐ€ id์ธ ๊ฒƒ์„ ์ œ๊ฑฐ
    setUsers(users.filter((user) => user.id !== id));
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} />
    </>
  );
}

export default App;

- ๋ถˆ๋ณ€์„ฑ์„ ์ง€ํ‚ค๋ฉด์„œ ํŠน์ • ์›์†Œ๋ฅผ ๋ฐฐ์—ด์—์„œ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด filter ๋ฐฐ์—ด ๋‚ด์žฅ ํ•จ์ˆ˜ ์‚ฌ์šฉ

- filter ํ•จ์ˆ˜๋Š” ๋ฐฐ์—ด์—์„œ ํŠน์ • ์กฐ๊ฑด์ด ๋งŒ์กฑํ•˜๋Š” ์›์†Œ๋“ค๋งŒ ์ถ”์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ๋งŒ๋“ค์–ด์คŒ

 

๋ฐฐ์—ด ํ•ญ๋ชฉ ์ˆ˜์ •

import React from "react";

function User({ user, onRemove, onToggle }) {
//cursor: ๋งˆ์šฐ์Šค ์˜ฌ๋ ธ์„ ๋•Œ ์ปค์„œ์˜ ๋ชจ์–‘ ๋ณ€๊ฒฝ
  return (
    <div>
      <b
        style={{ cursor: "pointer", color: user.active ? "green" : "black" }}
        onClick={() => onToggle(user.id)}
      >
        {user.username}
      </b>
      <span>({user.email})</span>
      <button onClick={() => onRemove(user.id)}>์‚ญ์ œ</button>
    </div>
  );
}

function UserList({ users, onRemove, onToggle }) {
  return (
    <div>
      {users.map((user) => (
        <User
          user={user}
          key={user.id}
          onRemove={onRemove}
          onToggle={onToggle}
        />
      ))}
    </div>
  );
}

export default UserList;
import React, { useRef, useState } from "react";
import UserList from "./UserList";
import CreateUser from "./CreateUser";

function App() {
  const [inputs, setInputs] = useState({
    username: "",
    email: "",
  });
  const { username, email } = inputs;
  const onChange = (e) => {
    const { name, value } = e.target;
    setInputs({
      ...inputs,
      [name]: value,
    });
  };
  const [users, setUsers] = useState([
    {
      id: 1,
      username: "velopert",
      email: "public.velopert@gmail.com",
      active: true,
    },
    {
      id: 2,
      username: "tester",
      email: "tester@example.com",
      active: false,
    },
    {
      id: 3,
      username: "liz",
      email: "liz@example.com",
      active: false,
    },
  ]);

  const nextId = useRef(4); //useRef() ์‚ฌ์šฉํ•  ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ๋„ฃ์–ด์ฃผ๋ฉด, ์ด ๊ฐ’์ด .current๊ฐ’์˜ ๊ธฐ๋ณธ๊ฐ’์ด ๋จ
  const onCreate = () => {
    const user = {
      id: nextId.current,
      username,
      email,
    };
    setUsers(users.concat(user));
    setInputs({
      username: "",
      email: "",
    });
    nextId.current += 1; //๊ฐ’ ์ˆ˜์ • ์‹œ, .current ๊ฐ’ ์ˆ˜์ •ํ•˜๋ฉด ๋˜๊ณ , ์กฐํšŒํ•  ๋•Œ๋„ .current์กฐํšŒํ•˜๋ฉด ๋จ
  };

  const onRemove = (id) => {
    //user.id๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ์›์†Œ๋งŒ ์ถ”์ถœํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ฆ
    //=user.id๊ฐ€ id์ธ ๊ฒƒ์„ ์ œ๊ฑฐ
    setUsers(users.filter((user) => user.id !== id));
  };
  
  const onToggle = (id) => {
    setUsers(
      users.map((user) =>  // ๋ฐฐ์—ด์˜ ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐฐ์—ด ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด mapํ•จ์ˆ˜ ์‚ฌ์šฉ
        user.id === id ? { ...user, active: !user.active } : user  //id๊ฐ’ ๋น„๊ตํ•˜์—ฌ ๊ฐ™์œผ๋ฉด active ๊ฐ’ ๋ฐ˜์ „, ์•„๋‹ ๊ฒฝ์šฐ ๊ทธ๋Œ€๋กœ ๋‘๊ธฐ
      )
    );
  };
  return (
    <>
      <CreateUser
        username={username}
        email={email}
        onChange={onChange}
        onCreate={onCreate}
      />
      <UserList users={users} onRemove={onRemove} onToggle={onToggle} />
    </>
  );
}

export default App;