관리 메뉴

공부기록용

React입문 1주차(반복컴포넌트01) 본문

📚강의록📚/스파르타)React

React입문 1주차(반복컴포넌트01)

과부하가즈아 2023. 6. 26. 19:45

🔴state 생성, 연결

🔴입력 값 추가하기

🔻코드뜯어보기

🔴입력 값 삭제하기


// ./src/App.js
import React from "react";
import './App.css';

const App = () => {
  // Javascript를 쓸 수 있는 영역
  // 함수가 시작되는 부분 바로 밑
  // return문 위에
  const arr = ['감자', '고구마', '오이', '가지', '옥수수'];


  return(
    // retur문 바로 밑은(return문 안에 쓰는 것) html 같이 생긴 부분을 작성하는 부분 
    // html같이 생겼지만 JSX문법 이라고 함
    // JSX : Javascritp와 XML(html이라고 생각)의 합성어
    // Javascript적인 요소를 쓰고 싶다면{ }안에 작성하면 됨
    <div className = "app-style" >
      {arr.filter(function(a){
        return a !== "가지";
      }).map(function(b){
        return <div className="component-style">{b}</div>
      })}

    </div >
  );
  
};

export default App;

import React from "react";
import './App.css'; // 🔥 반드시 App.css 파일을 import 해주기


const App = () => {

  const users = [ // 배열!
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ];

  return (
    <div className="app-style">
      {users.map(function (a) {
        return (
          <div className="component-style ">{a.age} - {a.name}</div>
        )
      })}
    </div>
  );

};

export default App;

> import 확인하기
> return에 멀티라인으로 들어가면 ()
> 멀티라인 시 상위 태그가 있어야 함
> js 요소 {}안에 기재
> map함수 사용시 받는 매개변수로 아무것이나 넣을 수 있고,
> 의미하는 바는 map함수로 돌려는 배열의 요소 하나하나로 생각할 것

💫map함수를 쓸 때, 반복적으로 return하는 부분들은 태그를 붙여줘야 한다. 

key = {a.id}
return (
  <div key={a.id} className="component-style ">{a.age} - {a.name}</div>
)

등록(렌더링을 다시해야 한다 -> state가 바뀌어야 한다. -> 예시에는 state는 없는 배열의 상태이다 -> state로 변경하기)

//기존 users 배열

const users = [ // 배열!
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ];

//useState를 이용한 상태값 만들기

const [users, setUsers] = useState([
  { id: 1, age: 30, name: "송중기" },
  { id: 2, age: 24, name: "송강" },
  { id: 3, age: 21, name: "김유정" },
  { id: 4, age: 29, name: "구교환" },
]);

state로 변경하고 연결하기, UI를 작성

변동되는 부분만 다시 렌더링해주기 위해서 변동되는 부분인 이름과 나이에 usestate해주고, 

import React, { useState } from "react"; // useState를 import해주는 것 확인
import './App.css';

const App = () => {

  const [users, setUsers] = useState([
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ]);


  // 아래 return에서 받아 오는, input안에 입력되는 값들이 바로바로 셋팅되는 것
  // 유저의 입력값을 담을 상태
  // 이름
  const [name, setName] = useState(''); // 이름이니까 

  // 나이
  const [age, setAge] = useState(''); // 나이니까


  return (
    <div>

      <div>

        이름 :&nbsp; <input 
        value={name} 
        onChange={(event) => {
          setName(event.target.value)  // 인풋 이벤트로 들어온 입력 값을 name의 값으로 업데이트
        }} />
        
        <br/>

        나이 :&nbsp; <input 
        value={age} 
        onChange={function(event){
          setAge(event.target.value)   // 인풋 이벤트로 들어온 입력 값을 age의 값으로 업데이트
        }} />

      </div>

      <div className="app-style">
        {users.map(function (a) {
          return (
            <div key={a.id} className="component-style ">{a.age} - {a.name}</div>
          )
        })}
      </div>

    </div>

  );

};

export default App;

담은 이름과 나이에 해당하는 값이 불려오도록 함

import React, { useState } from "react"; // useState를 import해주는 것 확인
import './App.css';

const App = () => {

  const [users, setUsers] = useState([
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ]);

  const [name, setName] = useState(''); // 이름
  const [age, setAge] = useState(''); // 나이


  // 이름과 나이 handler
  const nameChangeHandler = (event) => {
    setName(event.target.value)
  }
  const ageChangeHandler = function(event){
    setAge(event.target.value)
  }


  return (
    <div>

      <div>
        이름 :&nbsp; <input 
        value={name} 
        // 같음
        onChange={(event)=>nameChangeHandler(event)} /> 
        <br/>

        나이 :&nbsp; <input 
        value={age} 
        // 같음 event만 쓸꺼면 이렇게 해도 됨
        onChange={ageChangeHandler} />  
      </div>

      <div className="app-style">
        {users.map(function (a) {
          return (
            <div key={a.id} className="component-style ">{a.age} - {a.name}</div>
          )
        })}
      </div>

    </div>
  );
};

export default App;

1. `import React, { useState } from "react";`:
`React`와 `useState`를 import하고 있습니다. `useState`는 React에서 상태(state)를 관리하기 위해 사용하는 Hook입니다.

2. `const App = () => { ... }`:
`App`이라는 함수형 컴포넌트를 정의하고 있습니다. 함수형 컴포넌트는 React 컴포넌트를 정의하는 방법 중 하나입니다.

3. `const [users, setUsers] = useState([...]);`: 
`useState`를 사용하여 `users`라는 상태 변수와 그 상태를 갱신할 수 있는 `setUsers` 함수를 정의하고 있습니다.  `users` 상태 변수는 배열을 초기값으로 가지며, 각각의 요소는 `id`, `age`, `name`을 가지는 객체입니다.

4. `const [name, setName] = useState('');`와 `const [age, setAge] = useState('');`:
`name`과 `age`라는 상태 변수와 갱신 함수를 정의하고 있습니다.
`name`과 `age`는 각각 빈 문자열을 초기값으로 가지고 있습니다.

5. `nameChangeHandler`와 `ageChangeHandler`:
`nameChangeHandler` 함수는 인자로 전달받은 이벤트 객체의 `target.value` 값을 사용하여 `name` 상태를 갱신합니다. 
`ageChangeHandler` 함수는 함수 표현식을 사용하여 동일한 작업을 수행합니다.

이벤트 객체는 웹 애플리케이션에서 사용자의 동작(클릭, 입력 등)을 나타내는 정보를 포함하는 객체입니다. 
(이벤트 객체는 웹 애플리케이션에서 사용자의 동작(예: 클릭, 입력)을 나타내는 정보를 포함하고 있습니다.
예를 들어, 사용자가 버튼을 클릭하거나 입력 필드에 텍스트를 입력하는 경우에 해당합니다.
)


React에서 이벤트 핸들러 함수는 일반 JavaScript 함수와 마찬가지로 인자를 받을 수 있습니다. 이벤트 핸들러 함수에는 일반적으로 이벤트 객체가 첫 번째 인자로 전달됩니다.
function handleClick(event) {
  // 이벤트 핸들러의 로직
}

function handleChange(event) {
  // 이벤트 핸들러의 로직
}

// JSX 내부에서 이벤트 핸들러 등록
<button onClick={handleClick}>클릭</button>
<input type="text" onChange={handleChange} />

> handleClick 함수와 handleChange 함수는 모두 이벤트 객체를 첫 번째 인자로 받습니다. React는 이벤트가 발생하면 해당 이벤트 객체를 이벤트 핸들러 함수에 전달합니다.

> <button> 요소에 onClick 이벤트 핸들러를 등록한 경우, 사용자가 버튼을 클릭하면 handleClick 함수가 호출됩니다. 이때 React는 클릭 이벤트에 대한 정보를 담은 이벤트 객체를 handleClick 함수에 전달합니다.

> <input> 요소에 onChange 이벤트 핸들러를 등록한 경우, 사용자가 입력 필드에 텍스트를 입력하면 handleChange 함수가 호출됩니다. 이때 event.target<input> 요소를 가리키며, event.target.value는 사용자가 입력한 값입니다.
(이벤트 객체에는 다양한 속성과 메서드가 있습니다. 가장 일반적으로 사용되는 속성은 target입니다. target은 이벤트가 발생한 HTML 요소를 나타냅니다. 이를 통해 사용자가 클릭한 요소나 입력한 값을 확인할 수 있습니다.)



일반적으로, 이벤트 객체에는 여러 속성과 메서드가 있습니다. 그 중에서도 주로 사용되는 속성은 다음과 같습니다:

`target`: 이벤트가 발생한 HTML 요소를 나타냅니다. 일반적으로 이벤트가 발생한 요소의 값을 가져오기 위해 사용됩니다.
`currentTarget`: 이벤트 핸들러가 연결된 HTML 요소를 나타냅니다. `target`과 다를 수 있으며, 주로 이벤트 위임 패턴에서 사용됩니다.
`type`: 발생한 이벤트의 타입을 나타냅니다. 예를 들어, 클릭 이벤트인 경우 "click"이라는 값을 가지게 됩니다.


그 중에서도 `target` 속성은 자주 사용되는데, 이 속성은 이벤트가 발생한 HTML 요소 자체를 가리킵니다.

`target.value`는 일반적으로 입력 요소(`<input>`, `<textarea>`)에서 사용자의 입력 값을 가져오기 위해 사용됩니다.

예를 들어, 아래와 같은 `<input>` 요소가 있다고 가정해보겠습니다:
// jsx
<input type="text" onChange={nameChangeHandler} />​

`nameChangeHandler` 함수는 이벤트 객체를 인자로 받습니다.
이벤트 객체의
`target` 속성은 `<input>` 요소를 가리키며,
`target.value`는 해당 입력 요소에 입력된 값입니다.
값을 사용하여 `name` 상태를 갱신할 수 있습니다.



// jsx
const nameChangeHandler = (event) => {
  setName(event.target.value);
};​

따라서, 사용자가 `<input>`에 텍스트를 입력할 때마다 `nameChangeHandler` 함수가 실행되고, 
해당 입력 값이 `name` 상태로 설정됩니다. 

이를 통해 입력값을 실시간으로 추적하고 상태를 업데이트할 수 있습니다.

`onChange` 이벤트 핸들러는 React에서 입력 요소의 값이 변경될 때 실행되는 함수입니다. 

이 이벤트 핸들러를 사용하여 사용자의 입력에 반응하고, 입력 값에 대한 처리나 상태 업데이트를 수행할 수 있습니다.

`onChange` 이벤트 핸들러는 보통 `<input>`, `<textarea>`, `<select>`와 같은 입력 요소에 적용됩니다. 사용자가 입력 필드에 값을 입력하거나 선택을 변경할 때마다 `onChange` 이벤트가 발생하고, 등록된 이벤트 핸들러가 실행됩니다.

// jsx
function handleChange(event) {
  // 이벤트 핸들러의 로직
}

<input type="text" onChange={handleChange} />

> `handleChange` 함수는 이벤트 객체를 인자로 받습니다.
>> 이벤트 객체는 사용자의 입력 동작에 대한 정보를 담고 있습니다.
>> `event.target`을 통해 해당 입력 요소를 가리키고, `event.target.value`를 통해 입력한 값을 가져올 수 있습니다.
> `handleChange` 함수 내부에서는 주로 입력 값을 처리하거나 상태 업데이트를 수행합니다.
>> 예를 들어, 입력 값을 상태로 관리하는 경우, `setState` 함수를 사용하여 상태를 업데이트할 수 있습니다.

// jsx
const [name, setName] = useState('');

function handleChange(event) {
  setName(event.target.value);
}

<input type="text" value={name} onChange={handleChange} />

 

> `name` 상태 변수를 사용하여 `<input>` 요소의 값과 연결하고 있습니다.
> `handleChange` 함수가 호출되면 `event.target.value` 값을 사용하여 `name` 상태를 업데이트합니다.
> 이를 통해 사용자가 입력 필드에 값을 입력할 때마다 `name` 상태가 갱신되고, 입력 값이 실시간으로 반영됩니다.

`onChange` 이벤트 핸들러는 사용자 입력에 대한 실시간 반응을 구현하는 데 유용하며, React 컴포넌트에서 동적인 입력 처리를 할 때 자주 활용됩니다.


6. JSX 내부:
`name`과 `age`를 입력받기 위한 두 개의 `<input>` 요소가 있습니다.
`value` 속성을 통해 상태 변수와 바인딩되어 현재 상태를 표시하고,
`onChange` 이벤트 핸들러를 통해 상태를 업데이트합니다.
`users.map()` 함수를 사용하여 `users` 배열을 순회하고, 각 요소를 출력하는 `<div>` 요소가 있습니다.

`value` 속성을 통해 상태 변수와 바인딩하는 것은 React에서 입력 요소(`<input>`, `<textarea>`, `<select>` 등)의 현재 상태를 표시하기 위한 방법입니다.

일반적으로, React에서 입력 요소의 값을 관리하기 위해 상태(state)를 사용합니다.

상태 변수를 사용하여 입력 요소의 현재 값과 연결하고, 상태가 변경될 때마다 입력 요소가 업데이트되도록 할 수 있습니다. `value` 속성을 사용하면 상태 변수와 입력 요소의 값을 연결할 수 있습니다.

// JSX
const [name, setName] = useState(''); 

<input type="text" value={name} onChange={handleChange} />

 

> 위의 코드에서 `name`은 상태 변수이며, `setName`은 상태를 갱신하기 위한 함수입니다.
> `<input>` 요소의 `value` 속성은 `name` 상태 변수와 연결되어 현재의 값으로 설정됩니다.
>> 이로 인해, 초기에는 `name` 상태 변수가 빈 문자열로 초기화되어 있으므로, `<input>` 요소의 값도 빈 문자열로 표시됩니다.
> 사용자가 입력 필드에 텍스트를 입력하면 `handleChange` 함수가 호출되고, `setName` 함수를 통해 `name` 상태가 갱신됩니다.
> 이후 `name` 상태가 변경되면 React는 다시 렌더링하고, `<input>` 요소의 `value` 속성이 변경된 `name` 값으로 업데이트됩니다.

이를 통해 사용자가 입력한 값과 상태 변수의 값을 동기화할 수 있으며, 상태가 변경되면 입력 요소에 반영됩니다.

즉, `value` 속성을 통해 상태 변수와 바인딩하면 입력 요소는 항상 상태 변수의 값과 일치하도록 유지됩니다.

이를 통해 React는 상태 관리와 UI 간의 일관성을 유지하며, 입력 요소의 값을 동적으로 표시할 수 있습니다.

 

7. `export default App;`:
`App` 컴포넌트를 다른 파일에서 import할 수 있도록 내보내고 있습니다.

 


새로운 이름과 나이를 추가버튼을 누르면 나타나도록 추가해주기

import React, { useState } from "react"; // useState를 import해주는 것 확인
import './App.css';

const App = () => {

  const [users, setUsers] = useState([
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ]);


  const [name, setName] = useState(''); // 이름
  const [age, setAge] = useState(''); // 나이


  const nameChangeHandler = (event) => {
    setName(event.target.value)
  }
  const ageChangeHandler = function (event) {
    setAge(event.target.value)
  }
  

  // 추가 handler
  // 버튼을 누르면 추가가되는 것 
  const clickAddBtnHandler = function (event) {
    // 1. 새로운 형태의 { id: 1, age: 30, name: "송중기" }가 만들어져야함
    // 2. 만들어진 { id: 1, age: 30, name: "송중기" }가 기존의 배열에 추가되어야 한다.
    const newUser = {
      id: users.length + 1,  // users에서 id는 번호에 불과하니 길이로써 +1해준다.
      age: age,             // 받아오는게 age, name이니까 value에 그대로 적는다.
      name,           // 이렇게 key-value가 같은 경우 생략 가능하다.
    }

    // 원래있던 users배열을 spread operater을 이용해서 풀고, 
    // 입력된 배열(의 변수)를 추가
    // ✨불변성 유지
    setUsers([...users, newUser]);
  }

  return (
    <div>

      <div>
        이름 :&nbsp; <input
          value={name}
          // 같음
          onChange={(event) => nameChangeHandler(event)} />
        <br />

        나이 :&nbsp; <input
          value={age}
          // 같음 event만 쓸꺼면 이렇게 해도 됨
          onChange={ageChangeHandler} />
      </div>
      <br />

      <button onClick={clickAddBtnHandler}>추가!</button>

      <div className="app-style">
        {users.map(function (a) {
          return (
            <div key={a.id} className="component-style ">{a.age} - {a.name}</div>
          )
        })}
      </div>

    </div>
  );
};

export default App;

> users에서 id는 번호에 불과하니 길이로써 +1해준다.

> 받아오는게 age, name이니까 value에 그대로 적는다.

 

> 원래있던 users배열을 spread operater을 이용해서 풀고,

>  입력된 배열(의 변수)를 추가

> 불변성 유지

 

> 추가 버튼 핸들러: clickAddBtnHandler라는 이벤트 핸들러 함수를 정의하고 있습니다. 이 함수는 추가 버튼이 클릭될 때 호출되며, 입력된 이름과 나이를 사용하여 새로운 사용자 정보를 생성한 후 기존 users 배열에 추가합니다.

setUsers([...users, newUser]);는 users 상태 배열에 새로운 사용자 정보(newUser)를 추가하여 상태를 업데이트하는 코드입니다.

이를 통해 불변성(Immutability)을 유지하면서 새로운 배열을 생성하고 상태를 업데이트합니다.

해당 코드는 setUsers 함수를 호출하여 users 상태를 업데이트하는데, 전달하는 인자로 [...users, newUser]라는 배열을 사용하고 있습니다.

이 배열은 spread 연산자(...)를 사용하여 기존의 users 배열의 모든 요소를 복사하고, 그 뒤에 newUser를 추가한 새로운 배열을 생성합니다.

즉, 기존의 users 배열과 newUser 객체를 합쳐서 새로운 배열을 생성하고, 이를 setUsers 함수의 인자로 전달하여 상태를 업데이트합니다. 이렇게 함으로써 기존의 users 배열은 변경되지 않고, 새로운 배열이 생성되어 상태로 업데이트됩니다.

이러한 방식으로 상태를 업데이트하는 이유는 React에서 불변성을 유지하는 것이 중요하다고 간주되기 때문입니다.

불변성을 유지하면 React가 상태의 변화를 감지하고 컴포넌트를 효율적으로 업데이트할 수 있습니다. 또한, 불변성은 상태를 예측 가능하게 만들고 버그를 줄이는 데 도움을 줄 수 있습니다.

따라서, setUsers([...users, newUser]); 코드는 기존의 users 배열에 newUser를 추가하여 새로운 배열을 생성하고, 이를 통해 users 상태를 업데이트하는 것을 의미합니다.

> JSX 내부 구성: JSX를 사용하여 컴포넌트의 구조와 동작을 정의하고 있습니다. 입력 필드와 버튼을 렌더링하고, users 배열을 반복하여 사용자 정보를 표시하는 컴포넌트들을 생성합니다.

> 상태 업데이트: 입력 필드의 값과 users 배열은 상태 변수와 바인딩되어 있습니다. 상태 변수의 값이 변경될 때마다 React가 리렌더링되어 UI가 업데이트됩니다.

> JSX 반환: App 컴포넌트는 JSX를 반환하며, 이를 통해 UI가 렌더링됩니다.


삭제 구현

// 삭제
  const clickRemoveBtnHandler = (id) => {
    // const newUsers = users.filter(user => user.ld !== id);
    const newUsers = users.filter(function(user){
      return user.id !== id;
    })
    setUsers(newUsers);
  }

삭제 버튼이 클릭될 때 호출되며, 해당 사용자의 id를 기반으로 users 배열에서 해당 사용자를 제거한다.

 

clickRemoveBtnHandler 함수는 삭제 버튼이 클릭될 때 호출되는 이벤트 핸들러 함수입니다. 이 함수는 사용자의 id를 인자로 받아와서 users 배열에서 해당 사용자를 제거하고, 상태를 업데이트합니다.

 

함수 내부에서는 users 배열의 filter 메서드를 사용하여 새로운 배열인 newUsers를 생성합니다.(filter 메서드는 콜백 함수를 사용하여 배열을 필터링하고, 새로운 배열을 반환합니다)

 

콜백 함수는 각 배열 요소를 대상으로 실행되며, 해당 요소가 조건을 만족하면 true를 반환하여 새로운 배열에 포함시킵니다. 반대로 조건을 만족하지 않으면 false를 반환하여 해당 요소를 제외시킵니다.

 

function(user) {
	return user.id !== id; 
}

여기서 user는 배열의 각 요소를 나타내며, user.id !== id 조건은 현재 요소의 id와 인자로 받은 id가 다른 경우에만 true를 반환합니다.

 

즉, 삭제할 사용자의 id와 일치하지 않는 요소들만 필터링되어 newUsers 배열에 포함됩니다.

 

마지막으로 setUsers(newUsers)를 호출하여 users 상태를 newUsers 배열로 업데이트합니다. 이를 통해 삭제된 사용자가 반영된 UI가 렌더링됩니다.

<div className="app-style">
        {users.map(function (a) {
          return (
            <div key={a.id} className="component-style ">{a.age} - {a.name}
            <button onClick={() => clickRemoveBtnHandler(a.id)}>X</button> 
            </div>
          )
        })}
      </div>

> key={a.id}는 React에서 리스트를 렌더링할 때 필요한 고유한 키(key)를 지정하는 부분입니다.

`key`는 React에서 리스트를 렌더링할 때 각 항목에 고유한 식별자를 제공하는 특별한 속성입니다. 리스트를 업데이트할 때 React는 각 항목의 `key`를 사용하여 어떤 항목이 추가, 수정, 삭제되었는지 식별합니다.

`key` 속성을 제공함으로써 React는 항목들 간에 식별을 수행하고, 효율적인 업데이트를 수행할 수 있습니다.

React에서는 `key`를 사용하여 가상 DOM(Virtual DOM)의 업데이트 과정에서 추가, 수정, 삭제되는 요소를 빠르게 찾고 이를 반영하여 리렌더링 성능을 최적화합니다.

각 항목에 고유한 `key` 값을 지정함으로써 React는 리스트의 아이템을 구별하고, 아이템의 순서를 식별할 수 있습니다. 이렇게 고유한 `key`를 제공하면 React는 변경된 항목을 정확하게 찾아내어 필요한 부분만 업데이트하게 됩니다. 또한, `key`는 리스트 항목의 순서를 유지하기 위해 필요한 정보입니다.

따라서 `key` 속성은 React에서 리스트를 렌더링할 때 필요한 부분으로, 각 항목을 식별하기 위한 고유한 식별자로 사용됩니다. 일반적으로 고유한 `id` 값을 사용하며, 리스트의 항목이 고유한 식별자를 가지도록 보장해야 합니다.

> <button> 요소가 추가되어 있으며, onClick 이벤트 핸들러를 등록하고 있습니다. 삭제 버튼을 클릭하면 clickRemoveBtnHandler(a.id) 함수가 호출되고, 해당 사용자의 id가 인자로 전달됩니다. 이를 통해 해당 사용자를 삭제하는 기능이 동작하게 됩니다.

import React, { useState } from "react"; // useState를 import해주는 것 확인
import './App.css';

const App = () => {

  const [users, setUsers] = useState([
    { id: 1, age: 30, name: "송중기" },
    { id: 2, age: 24, name: "송강" },
    { id: 3, age: 21, name: "김유정" },
    { id: 4, age: 29, name: "구교환" },
  ]);


  // 아래 return에서 받아 오는, input안에 입력되는 값들이 바로바로 셋팅되는 것
  // 이름
  const [name, setName] = useState(''); // 이름이니까 

  // 나이
  const [age, setAge] = useState(''); // 나이니까

  // 이름과 나이 handler
  const nameChangeHandler = (event) => {
    setName(event.target.value)
  }
  const ageChangeHandler = function (event) {
    setAge(event.target.value)
  }

  // 추가 
  const clickAddBtnHandler = function (event) {
   
    const newUser = {
      id: users.length + 1, 
      age: age,            
      name,          
    }

    // ✨불변성 유지
    setUsers([...users, newUser]);
  }


  // 삭제
  const clickRemoveBtnHandler = (id) => {
    // const newUsers = users.filter(user => user.ld !== id);
    const newUsers = users.filter(function(user){
      return user.id !== id;
    })
    setUsers(newUsers);
  }

  return (
    <div>

      <div>
        이름 :&nbsp; <input
          value={name}
          // 같음
          onChange={(event) => nameChangeHandler(event)} />
        <br />

        나이 :&nbsp; <input
          value={age}
          // 같음 event만 쓸꺼면 이렇게 해도 됨
          onChange={ageChangeHandler} />
      </div>
      <br />

      <button onClick={clickAddBtnHandler}>추가!</button>

      <div className="app-style">
        {users.map(function (a) {
          return (
            <div key={a.id} className="component-style ">{a.age} - {a.name}
            <button onClick={() => clickRemoveBtnHandler(a.id)}>X</button> 
            </div>
          )
        })}
      </div>

    </div>
  );
};

export default App;

Comments