78일차 (2) - React (목표앱 - 목표 추가, 삭제)

Yohan·2024년 6월 15일
0

코딩기록

목록 보기
120/156
post-custom-banner

input에 입력한 것을 추가하고 삭제하는 기능을 학습


목표 추가

  1. 부모 컴포넌트인 App.js에서 CourseInput.js로 목표추가 함수를 onAdd이름으로 내려줌
    -> 나중에 CourseInput.js에서 받은 데이터를 실시간 화면 렌더링 해야하므로 상태변경 감지를 위해 setter인 setGoals사용
const App = () => {
	
  // 기본 데이터는 DUMMY_DATA로 초기화
  const [goals, setGoals] = useState(DUMMY_DATA);

  // CourseInput에게 전달할 함수
  const addGoalHandler = (goalObject) => {
    setGoals([...goals, goalObject]);
  };


  };
  
    return (
    <div>
      <section id="goal-form">
        <CourseInput onAdd={addGoalHandler} />
      </section>
    </div>
  );
  1. CourseInput.js에서 내려받은 함수에 데이터를 담아 App.js로 다시 올려줌 (상향식)
  • 입력값은 input 하나기 때문에 단일값으로 상태관리
    -> 입력값에 대한 상태관리를 위해 useState 사용
    -> 입력값이 바뀔 때 필요한 이벤트 핸들러 사용
    -> 폼을 전송하기위해 필요한 이벤트 핸들러 사용
import React, {useState} from 'react';
import './CourseInput.css';
import Button from '../UI/Button';

const CourseInput = ({ onAdd }) => {

  // 입력값 상태관리
  const [enteredText, setEnteredText] = useState('');

  // 입력값 바뀔 때 이벤트 핸들러
  const goalAddHandler = e => {
    setEnteredText(e.target.value);
  }

  // 폼 전송 이벤트 핸들러
  const formSubmitHandler = e => {
    e.preventDefault();

    const newGoalObject = {
      id: Math.random().toString(),
      text: enteredText
    };
    console.log(newGoalObject);

    // 부모 컴포넌트로 데이터 보내기
    onAdd(newGoalObject);

    // input 비우기
    setEnteredText('');
  }

  return (
    <form onSubmit={formSubmitHandler}>
      <div className="form-control">
        <label>나의 목표</label>
        <input type="text"
        value={enteredText}
        onChange={goalAddHandler}
        />
      </div>
      <Button type="submit">목표 추가하기</Button>
    </form>
  );
};

export default CourseInput;

목표 삭제

  1. 부모 컴포넌트인 App.js에서 CourseItem.js로 목표삭제 함수를 onDelete 이름으로 내려줌
    -> id가 일치할 경우 삭제하는 것으로 설정
const App = () => {

  const [goals, setGoals] = useState(DUMMY_DATA);

  // CouseItem에게 전달할 함수
  const deleteGoalHandler = (id) => {

    // 1. for문으로 삭제
    // let index = -1;
    // for (let i = 0; i < goals.length; i++) {
    //   if (goals[i].id === id) {
    //     index = i;
    //     break;
    //   }
    // }

    // goals.splice(index, 1);
    
    // setGoals([...goals]);

    // 2. findIndex
    // goals.splice(goals.findIndex(g => g.id === id), 1);

    // 3. filter, 일치하지 않은 애들은 필터 => 즉, 일치하는 애들만 선택되어서 삭제
    setGoals(goals.filter(g => g.id != id));


  };
  • CourseList.js
    • key를 꼭 전달! (고유)
import React from 'react';
import './CourseList.css';
import CourseItem from './CourseItem';

const CourseList = ({ items, onDelete }) => {
  return (
    <ul className='goal-list'>
      {
        items.map(item => <
          CourseItem
          key={item.id}
          item={item}
          onDelete={onDelete}
          />)
      }
    </ul>
  );
};
export default CourseList;
  1. 자식컴포넌트인 CourseItem.js에서 부모컴포넌트인 App.js로 삭제 대상의 id 데이터를 함수에 담아 올린다.
import React from 'react';
import './CourseItem.css';

const CourseItem = ({ item, onDelete }) => {

  const deleteHandler = e => {
    console.log('삭제 해줘');
    // 여기서 App.js에게 삭제 대상의 id를 전달
    onDelete(item.id);
  }

  return <li className="goal-item" onClick={deleteHandler}>{item.text}</li>;
};

export default CourseItem;
  1. 클릭하면 id가 일치시 삭제됨
profile
백엔드 개발자
post-custom-banner

0개의 댓글