Open9
ReactスターターっぽくTodoアプリをつくる
create-react-app×TypeScript の環境をつくる
からの、Todoアプリの作成をおこなおう
作りたいもの
・Todoを追加できる
・Todoを削除できる
・Todoを移動できる
ながれ
・つくる
・みてみる
・修正する
→繰り返す
参考
Udemy:【2022年最新】React完全入門ガイド|Hooks、Next.js、Redux、TypeScript
つくる
まずは作ってみたいので、構成はむずかしく考えない
(考えすぎて沼に陥りがちである..)
ファイルの整理
create-react-appで作成されたファイルを削除していく
logo.svg
react-app-env.d.ts
App.test.tsx
setupTests.ts
reportWebVitals.ts
📝 reportWebVitals.ts
・WebVitalsを計測するもの
・計測対象の指標
LCP(Largest Contentful Paint) → ページの読み込みスピード
CLS(Cumulative Layout Shift) → ページ表示の安定性
FID(First Input Delay) → クリックした際などの応答性
App.tsx
要素を並べる。
App.tsx
import './App.css'
import { useState } from 'react'
import List from 'components/List'
import Input from 'components/Input'
export interface TodoList {
id: number
content: string
}
const App = () => {
const [todoList, setTodoList] = useState<TodoList[]>([
{ id: 1, content: '食料:たまごサラダの材料' },
{ id: 2, content: '食料:豚肉、鶏むね肉' },
{ id: 3, content: 'タスク:整体の予約' },
])
const deleteTodo = (id: number) => {
/**完了したら削除*/
const newTodoList = todoList.filter((todo) => todo.id !== id)
return setTodoList(newTodoList)
}
const addTodo = (newTodo: TodoList) => {
/**タスクの追加*/
setTodoList((prev) => [...prev, newTodo])
}
return (
<>
<div className="App">
<header className="App-header">React Starter * Todo</header>
<Input addTodo={addTodo} />
<List todoList={todoList} deleteTodo={deleteTodo} />
</div>
</>
)
}
export default App
List.tsx
タスクリストを並べる
components/List.tsx
import { TodoList } from 'App'
type PropsList = {
todoList: TodoList[]
deleteTodo: (id: number) => void
}
const List: React.FC<PropsList> = (props) => {
const completeTodo = (id: number) => {
console.log('completed!')
props.deleteTodo(id)
return
}
return (
<ul>
{props.todoList.map((todo) => {
return (
<li key={todo.id}>
<button onClick={() => completeTodo(todo.id)} value={todo.id}>
完了
</button>
{todo.content}
</li>
)
})}
</ul>
)
}
export default List
📝 react/prop-types
prop-types エラーの解消
.eslintrc.yml
overrides:
- files: ['**/*.tsx']
rules:
'react/prop-types': 'off'
Input.tsx
components/Input.tsx
/**
* Input.tsx
* タスク追加の処理
*/
import { useState } from 'react'
import { TodoList } from 'App'
interface PropsInput {
addTodo: (arg: TodoList) => void
}
const Input: React.FC<PropsInput> = (props) => {
const [input, setInput] = useState('')
/* changeEvent */
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInput(e.target.value)
}
const createInput = (content: string) => {
const newInput = {
id: Math.floor(Math.random() * 1e5),
content: content,
}
props.addTodo(newInput)
setInput('') //追加後は空白にする
}
return (
<>
<input placeholder="タスクを入力" value={input} onChange={handleInputChange}></input>
<button onClick={() => createInput(input)}>追加</button>
</>
)
}
export default Input