▼ index.jsx 중간 제출 (파일나누기전 전체)
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
function TodoForm({ onSubmit }) {
const [todoText, setTodoText] = useState('');
const handleChange = (e) => setTodoText(e.target.value);
const handleSubmit = (e) => {
e.preventDefault();
if (!todoText) {
// eslint-disable-next-line no-alert
//밑에 alert에 대해 ESLint 비활성화하려면 위에꺼 작성
alert('할 일을 입력해 주세요😀');
return;
}
if (onSubmit) {
onSubmit(todoText);
}
setTodoText('');
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="할 일을 입력해주세요."
onChange={handleChange}
value={todoText}
/>
<button type="submit">추가</button>
</form>
</div>
);
}
function Todos({ todoItems, onClick }) {
if (todoItems.length === 0) {
return (
<p>
할 일이 없어요! 🙅♀️
</p>
);
}
return (
<ol>
{
todoItems.map(({ id, todo }) => (
<Todo
key={id}
id={id}
text={todo}
onClick={() => onClick(id)}
/>
))
}
</ol>
);
}
function Todo({ text, onClick }) {
return (
<li>
<span>{text}</span>
<button type="button" onClick={onClick}>완료</button>
</li>
);
}
function TodoPage({
onSubmit, todoItems, onClick,
}) {
return (
<div>
<p>assignment2</p>
<h3>To-do</h3>
<TodoForm
onSubmit={onSubmit}
/>
<Todos todoItems={todoItems} onClick={onClick} />
</div>
);
}
function App() {
const [todoItems, setTodoItems] = useState([]);
const handleSubmit = (todoItem) => {
setTodoItems([
...todoItems, {
id: Date.now(),
todo: todoItem,
},
]);
};
const handleDelete = (todoId) => {
setTodoItems(
todoItems.filter((item) => item.id !== todoId),
);
};
// Array.filter() 조건에 해당하는 걸 남겨서 배열로 return해줌 /누른 item의 id와 id가 같지않은걸 배열로 남겼기 때문에 해당 클릭한 id꺼만 지워짐
return (
<TodoPage onSubmit={handleSubmit} todoItems={todoItems} onClick={handleDelete} />
);
}
ReactDOM.render(
<App />,
document.getElementById('app'),
);
▼ 화면구현
리뷰받고 수정 제출2
0. import React from 'react'; 리액트17 버전 이후부터는 생략이 가능
생략하고 babel.config.js 수정함
방법:지난번 블로그 참고
+
라이브러리 import 와 로컬 파일 구분하기 위해 띄어주기
import { useState } from 'react';
import TodoForm from './TodoForm';
1.
▼ 기존 코드에서 if (onSubmit) {.. if 조건문 불필요
const handleSubmit = (e) => {
e.preventDefault();
if (!todoText) {
// eslint-disable-next-line no-alert
//밑에 alert에 대해 ESLint 비활성화하려면 위에꺼 작성
alert('할 일을 입력해 주세요😀');
return;
}
if (onSubmit) {
onSubmit(todoText);
}
setTodoText('');
};
▼ 아래와 같이 수정함
if (!todoText) {
...
}
onSubmit(todoText); //if제외
setTodoText('');
..
2. props drilling해결하기
해결: App.jsx에서 선언했던 state,함수를 TodoPage.jsx로 옮겼다.
3. TodoForm.jsx 에서 함수를 선언하고 관리했는데 이를 수정하는 작업이 필요
해결: TodoForm.jsx를 아래와 같이 변경하고,
기존 코드를 TodoPage.jsx 에서 관리되도록 옮겨 수정함
아래는 수정한 전체 제출 코드
▼ TodoForm
function TodoForm({
onSubmit,
todoText,
handleChange,
}) {
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(todoText);
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="할 일을 입력해주세요."
onChange={handleChange}
value={todoText}
/>
<button type="submit">추가</button>
</form>
</div>
);
}
export default TodoForm;
▼ TodoPage.jsx
import { useState } from 'react';
import TodoForm from './TodoForm';
import Todos from './Todos';
function TodoPage() {
const [todoItems, setTodoItems] = useState([]);
const [todoText, setTodoText] = useState('');
const handleChange = (e) => setTodoText(e.target.value);
const handleSubmit = (todoItem) => {
if (!todoText) {
alert('할 일을 입력해 주세요😀');
return;
}
setTodoItems([
...todoItems, {
id: Date.now(),
todo: todoItem,
},
]);
setTodoText('');
};
const handleDelete = (todoId) => {
setTodoItems(
todoItems.filter((item) => item.id !== todoId),
);
};
return (
<div>
<p>assignment2</p>
<h3>To-do</h3>
<TodoForm
onSubmit={handleSubmit}
todoText={todoText}
handleChange={handleChange}
/>
<Todos todoItems={todoItems} onClick={handleDelete} />
</div>
);
}
export default TodoPage;
리뷰받고 수정 제출3
1. App이 여러 페이지로 구성되어 있지 않으므로 TodoPage.jsx를 없애고 App으로 내용을 넘겨줌
2. TodoForm.jsx에서 아래의 handleSubmit 함수를 제거하고 App.jsx로 옮겨 관리하게 수정
해결: App.jsx 에서 아래와 같이 코드 수정(매개변수를 받아오는 것이 아닌, todoText를 직접설정해주자 적용됨)
const handleSubmit = (e) => {
e.preventDefault();
if (!todoText) {
alert('할 일을 입력해 주세요😀');
return;
}
setTodoItems([
...todoItems, {
id: Date.now(),
todo: todoText,
},
]);
setTodoText('');
};
리뷰받고 수정 제출4
+handle~, on~ 구분을 통해 실제 일을 '처리'하는 관점과 '사용'하는 입장에서 바라볼 때의 의도를 각각 드러내줄 수 있다.
▼ 최종 전체 코드
index.jsx
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
App.jsx
import { useState } from 'react';
import TodoForm from './TodoForm';
import Todos from './Todos';
function App() {
const [todoItems, setTodoItems] = useState([]);
const [todoText, setTodoText] = useState('');
const handleChange = (e) => {
setTodoText(e.target.value);
};
const handleSubmit = (e) => {
e.preventDefault();
if (!todoText) {
// eslint-disable-next-line no-alert
alert('할 일을 입력해 주세요😀');
return;
}
setTodoItems([
...todoItems, {
id: Date.now(),
todo: todoText,
},
]);
setTodoText('');
};
const handleDelete = (todoId) => {
setTodoItems(
todoItems.filter((item) => item.id !== todoId),
);
};
return (
<div>
<p>assignment2</p>
<h3>To-do</h3>
<TodoForm
onSubmit={handleSubmit}
onChange={handleChange}
todoText={todoText}
/>
<Todos todoItems={todoItems} onClick={handleDelete} />
</div>
);
}
export default App;
TodoForm.jsx
function TodoForm({
onSubmit,
onChange,
todoText,
}) {
return (
<div>
<form onSubmit={onSubmit}>
<input
type="text"
placeholder="할 일을 입력해주세요."
onChange={onChange}
value={todoText}
/>
<button type="submit">추가</button>
</form>
</div>
);
}
export default TodoForm;
Todos.jsx
import Todo from './Todo';
function Todos({ todoItems, onClick }) {
if (todoItems.length === 0) {
return (
<p>
할 일이 없어요! 🙅♀️
</p>
);
}
return (
<ol>
{
todoItems.map(({ id, todo }) => (
<Todo
key={id}
id={id}
text={todo}
onClick={() => onClick(id)}
/>
))
}
</ol>
);
}
export default Todos;
Todo.jsx
function Todo({ text, onClick }) {
return (
<li>
<span>{text}</span>
<button type="button" onClick={onClick}>완료</button>
</li>
);
}
export default Todo;
할 일을 입력해서 등록하고, 완료할 수 있는 간단한 To-do 리스트를 만들어주세요.
기능 구현
- 사용자는 할 일을 입력할 수 있습니다.
- 사용자는 추가 버튼을 눌러서 할 일을 추가할 수 있습니다.
- 사용자는 할 일 목록을 볼 수 있습니다.
- 사용자는 완료 버튼을 눌러 할 일을 삭제할 수 있습니다.
제한 조건
- if는 사용할 수 있어도 else 사용하실 수 없습니다. GuardClauses 방법을 사용해주세요.
- switch는 사용하실 수 없습니다.
- let은 사용하실 수 없습니다. const만을 사용하여 문제를 해결해주세요.
- 함수 이름과 변수 이름에 줄임말은 사용하실 수 없습니다. 길더라도 명확하게 써주세요.
- indent(인덴트, 들여쓰기) depth를 1로 유지해주세요. 예를 들어, for문 안에 if문이 있으면 indent depth는 2입니다. depth를 줄이는 좋은 방법은 함수(또는 메소드)를 분리하면 됩니다.
요구사항
- ESLint를 돌린 결과 아무런 문제가 없어야 합니다.
- 모든 인수 테스트를 통과시켜야 합니다.
- 한 파일에는 하나의 컴포넌트만 있어야 합니다.
Hint
과제를 위해선 반드시 아래 2개의 문서를 읽어주세요.
'CodeSoom- React 13기' 카테고리의 다른 글
[코드숨] 리액트 13기 -2강/ 과제2 - 간단한 Todo App 만들기(과제풀이) (0) | 2022.10.22 |
---|---|
[코드숨] 리액트 13기 -2강/ 과제1-Counter 앱 만들고 파일 분리하기(과제풀이) (0) | 2022.10.22 |
[코드숨] 리액트 13기 -2강/ 과제1-Counter 앱 만들고 파일 분리하기 (0) | 2022.10.19 |
[코드숨] 리액트 13기 -2강/ 2. React(useState, 관심사의 분리) (0) | 2022.10.19 |
[코드숨] 리액트 13기 -2강/ 1. React (0) | 2022.10.19 |