본문 바로가기

CodeSoom- React 13기

[코드숨] 리액트 13기 -2강/ 과제2 - 간단한 Todo App 만들기(과제풀이)

1.

에러  Objects are not valid as a React child....

object 를 못보여준다.

 

{JSON.stringify(..)}  : JSON형태로 확인 가능 =>객체이기때문에 .title 이런식으로 메소드를 통해 이용해야했음
export default function List({ tasks }) {
  return (
    <p>
      {JSON.stringify(tasks)}
    </p>
  );
 }

 

2.

그냥 배열이면 이렇게 쓰지만

 

state 경우 이렇게도 작성이 가능하다

 

3. Destructuring 디스트럭쳐링 

: 기존에 구조를 가지고 있던 객체(Array or Object)를 파괴(Destructure)하여 별도의 변수에 값을 할당하는 것

=> 배열이나 객체 안의 어떤 값을 추출할 때 쉽게 받아오는 방법

 

>  위 코드를 아래와 같이 디스트럭쳐링 할 수 있음


최종 코드

 

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';

import App from './App';

ReactDOM.render(
  <App />,
  document.getElementById('app'),
);// ReactDOM을 이용해 그려줌

 

App.jsx

import React, { useState } from 'react';

import Page from './Page';

export default function App() {
  const [state, setState] = useState({
    newId: 100,
    taskTitle: '',
    tasks: [
      { id: 1, title: '아무것도 하지 않기#1' },
      { id: 2, title: '아무것도 하지 않기#2' },
    ],
  });

  const { newId, taskTitle, tasks } = state;

  function handleChangeTitle(event) {
    setState({
      ...state, // ... spread :객체 혹은 배열을 펼칠수있다. / 원래있던게 그대로 들어감,그뒤에 다시 밑에 코드처럼 들어가면 덮어써져서 업데이트가 되는 것
      newId,
      taskTitle: event.target.value,
      tasks,
    });
    console.log(event.target.value);
  }
  /*  event.target.value
  Input에서 onChange는 event를 돌려주는데 event.target하면 input을 받는 dom 객체를 얻을 수있다, .value를 하면 그 입력값을 얻을 수 있음 */

  function handleClickAddTask() {
    setState({
      ...state,
      newId: newId + 1,
      taskTitle: '', // 클릭전에 입력된 값 지우게 설정
      tasks: [...tasks, { id: newId, title: taskTitle }],
    });
  }

  function handleClickDeleteTask(id) {
    setState({
      ...state,
      tasks: tasks.filter((task) => task.id !== id),
      // task의 id가 누른 id랑 다른 경우는 둔다.(즉 같은건 삭제)
    });
  }

  return (
    <Page
      taskTitle={taskTitle}
      onChangeTitle={handleChangeTitle}
      onClickAddTask={handleClickAddTask}
      tasks={tasks}
      onClickDeleteTask={handleClickDeleteTask}
    />
  );
}
// App에서 처리,관리하는 게 있고 나머지 컴포넌트에는 UI를 작성

 

Page.jsx

import React from 'react';
import Input from './Input';
import List from './List';

export default function Page({
  taskTitle, onChangeTitle, onClickAddTask,
  tasks, onClickDeleteTask,
}) {
  return (
    <div>
      <h1>To-do</h1>
      <Input
        value={taskTitle}
        onChange={onChangeTitle}
        onClick={onClickAddTask}
      />
      {/* taskTitle={taskTitle} 해도 되지만 범용적으로 사용하고 싶으면 value라고도 함 ,
        onChange =>값이 바뀔때
      */}
      <List
        tasks={tasks}
        onClickDelete={onClickDeleteTask}
      />
    </div>
  );
}

 

Input.jsx

import React from 'react';

export default function Input({ value, onChange, onClick }) {
  return (
    <p>
      <input
        type="text"
        placeholder="할 일을 입력해주세요."
        value={value}
        onChange={onChange}
      />
      <button type="button" onClick={onClick}>
        추가
      </button>
    </p>
  );
}

 

List.jsx

import React from 'react';

import Item from './Item';

export default function List({ tasks, onClickDelete }) {
  return (
    <ol>
      {tasks.map((task) => (
        <Item key={task.id} task={task} onClickDelete={onClickDelete} />
      ))}

    </ol>
  );
}

 

Item.jsx

import React from 'react';

export default function Item({ task: { id, title }, onClickDelete }) {
  return (
    <li>
      {title}
      <button type="button" onClick={() => onClickDelete(id)}>
        Done
      </button>
    </li>
  );
}