본문 바로가기
강의/스파르타코딩클럽

[리액트 입문주차] 1-17 Styling ~ 1-21 컴포넌트 분리하기

by gardenii 2023. 6. 24.

1-17 Styling, Map

< 분리 전 >

import React from "react";

const App = () => {
  const style = {
    padding: "100px",
    display: "flex",
    gap: "12px",
  };

  const squareStyle = {
    width: "100px",
    height: "100px",
    border: "1px solid green",
    borderRadius: "10px",
		display: "flex",
    alignItems: "center",
    justifyContent: "center",
  };

  return (
    <div style={style}>
      <div style={squareStyle}>감자</div>
      <div style={squareStyle}>고구마</div>
      <div style={squareStyle}>오이</div>
      <div style={squareStyle}>가지</div>
      <div style={squareStyle}>옥수수</div>
    </div>
  );
};

export default App;

< 분리 후 >

1-18 반복되는 컴포넌트 처리하기 (1)

1. Map(), filter() 메서드란?

- Map() : 배열을 가공 조건에 따라 가공하여 리턴하는 함수

- filter() : 배열 요소 중 조건에 알맞은 요소만 리턴하는 함수

2. 메서드를 사용하여 반복되는 컴포넌트 처리

1. 채소 이름 배열로 선언

const vegetables = ["감자", "고구마", "오이", "가지", "옥수수"];

2. map()으로 모두 출력

return (
    <div className="app-style">
      {vegetables.map((vegetableName) => {
        return (
          <div className="square-style" key={vegetableName}>
            {vegetableName}
          </div>
        );
      })}
    </div>
  );

3. filter()로 오이가 아닌 것을 거르고, 다시 map()으로 출력

return (
    <div className="app-style">
      {vegetables
        .filter(function (item) {
          return item !== "오이";
        })
        .map((vegetableName) => {
          return (
            <div className="square-style" key={vegetableName}>
              {vegetableName}
            </div>
          );
        })}
    </div>
  );

1-19 반복되는 컴포넌트 처리하기 (2)

1. 객체가 담긴 배열 다루기

import React from 'react';
import './App.css'; // 🔥 반드시 App.css 파일을 import 해줘야 합니다.

//  User 컴포넌트를 분리해서 구현
function User(props) {
  return (
    <div>{props.user.age}살 - {props.user.name}</div>
  );
}

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-container">
      {users.map((user) => {
        return <User user={user} key={user.id} />;
      })}
    </div>
  );
};

export default App;

 

2. 반복적인 반환 요소에 필요한 Key값

- 반복되는 요소에 유니크한 key값이 꼭 필요

3. 객체 배열 State로 변경하기

//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: '구교환' },
  ]);

4. 유저 추가하기 (컴포넌트 분리된 경우)

* &nbsp; 는 공백 문자를 뜻함

import React, { useState } from "react";
import "./App.css"; // 🔥 반드시 App.css 파일을 import 해줘야 합니다.

//  User 컴포넌트를 분리해서 구현
function User(props) {
  return (
    <div className="squareStyle">
      {props.user.age}살 - {props.user.name}
    </div>
  );
}

const App = () => {
  //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: "구교환" },
  ]);

  const [name, setName] = useState("");
  const [age, setAge] = useState("");

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

  const clickAddButtonHandler = () => {
    // 1.{ id: 1, age: 30, name: "송중기" } 형태를 만든다
    // 2. 배열에 더한다.
    const newUser = {
      id: users.length + 1,
      age,
      name,
    };
    setUsers([...users, newUser]);
  };

  return (
    <>
      <div>
        이름 :&nbsp;
        <input value={name} onChange={nameChangeHandler} />
        <br></br>
        나이 :&nbsp;
        <input value={age} onChange={ageChangeHandler} />
        <br></br>
        <button onClick={clickAddButtonHandler}>추가</button>
      </div>
      <div className="app-container">
        {users.map((user) => {
          return <User user={user} key={user.id} />;
        })}
      </div>
    </>
  );
};

export default App;

- id 생성하기 : 기존 배열 길이에서 + 1하기

- age와 name은 key, value 값이 일치하므로 생략

- setUser를 통해 배열을 바꿀 때는 전개 연산자를 사용해 복사해준 후, 그 값에 추가해주어 다시 반환

- 헷갈리는 점 정리

5. 유저 삭제하기 (컴포넌트 분리된 경우)

1. 각 User에 삭제 버튼 만들기

//  User 컴포넌트
function User(props) {
  return (
    <div className="squareStyle">
      {props.user.age}살 - {props.user.name}
      <button onClick={}>❌</button>
    </div>
  );
}

2. App 컴포넌트에 삭제하는 함수 clickRemoveButtonHandler 만들기

const clickRemoveButtonHandler = () => {};

3. 자식 컴포넌트 return 할 때, users의 각 유저를 map하면서 props로 위 함수도 함께 넘겨주기 

return (
    <>
      <div>
        이름 :&nbsp;
        <input value={name} onChange={nameChangeHandler} />
        <br></br>
        나이 :&nbsp;
        <input value={age} onChange={ageChangeHandler} />
        <br></br>
        <button onClick={clickAddButtonHandler}>추가</button>
      </div>
      <div className="app-container">
        {users.map((user) => {
          return (
            <User
              user={user}
              key={user.id}
              handleDelete={clickRemoveButtonHandler}
            />
          );
        })}
      </div>
    </>
  );

4. User 컴포넌트에서 props로 받아 온 함수를 onclick에 넣어줌

5. 삭제를 위해 함수에 props로 넘어온 현재 요소의 user.id를 넣어줌

* onClick에서 함수에 인자를 전해주고 싶을 때는 앞에 () => 를 붙여줘야 함

function User(props) {
  return (
    <div className="squareStyle">
      {props.user.age}살 - {props.user.name}
      <button onClick={() => props.handleDelete(props.user.id)}>❌</button>
    </div>
  );
}

6. App 컴포넌트에서 삭제 함수를 구현해 줌

- filter()를 이용해 users 배열에서, 인자로 넘겨받은 id와 일치하지 않는 값만 걸러 새로운 배열을 만들어 준 후 newUser 변수에 넣어줌

- 위 과정은 넘겨받은 id와 일치하는 값만 false로 빼버리므로, 삭제 기능이 됨

- 걸러진 배열이 담긴 newUsers를 setUser를 통해 업데이트 해줌

const clickRemoveButtonHandler = (id) => {
    const newUsers = users.filter((user) => user.id !== id);
    setUsers(newUsers);
  };

1-21 컴포넌트 분리하기(독립 컴포넌트)

추가 버튼 컴포넌트로 분리해보기

1. AddButton 컴포넌트 생성

function AddButton() {}

2. 원래 버튼 값 가져와서 AddButton 컴포넌트에 넣어주고, 그 자리에는 컴포넌트 넣어주기

// AddButton 컴포넌트
function AddButton() {
  return <button onClick={clickAddButtonHandler}></button>;
}

// App 컴포넌트
<AddButton/>

3. AddButton 컴포넌트에서 사용할 수 있도록 App 컴포넌트에서 handleAdd 이름으로 clickAddButtonHandler props로 넘겨주기

<AddButton handleAdd={clickAddButtonHandler}>추가</AddButton>

4. AddButton 컴포넌트에서 받아온 props 함수를 onclick에 넣어주기

function AddButton({ handleAdd }) {
  return <button onClick={handleAdd}>추가</button>;
}

// 아래와 같음
function AddButton(props) {
  return <button onClick={props.handleAdd}>추가</button>;
}

* 함수는 props로 넘겨줄 때 바로 넘겨주면 안되고, 중괄호로 감싸주어 props에 넣어주어야 함

* 구조분해할당

* 중괄호 없이 넘겨주면 함수의 실행 결과가 전달됨

5. children 사용해보기

<AddButton handleAdd={clickAddButtonHandler}>추가</AddButton>

- App 컴포넌트 사이에 children으로 추가 넘겨주기

- 넘겨받은 props와 children사용하기

function AddButton(props) {
  return <button onClick={props.handleAdd}>{props.children}</button>;
}

// OR
function AddButton({handleAdd, children}) {
  return <button onClick={handleAdd}>{children}</button>;
}

6. 컴포넌트 파일 분리

- src 폴더 내부에 component 폴더 생성

- component 폴더에 App 컴포넌트 내부에 작성했던 컴포넌트들을 .jsx 파일로 생성

- export default [컴포넌트 이름] 해주어 내보내기 해줌

- App 컴포넌트 상위에 import 해 줌

component 폴더 내부에 각 컴포넌트 생성 / 각 컴포넌트 내부에서 export
컴포넌트 import