前提・実現したいこと
reactにてtodoアプリを作成しています。
そこで、categoryの値を増やすhandleStateIncreaseという関数を設定し、クリックするごとに未着手→進行中→完了となるようにしたいのですが、完了状態になったあとにクリックすると下記のエラーメッセージが出てしまいます。
そこで、クリックしてcategoryの数値が3になった(完了と表示される)あとにクリックすると1(未着手)の状態に戻るというようにしたいのですが、調べてもなかなかうまく行かなかったのでなにかアドバイスがほしいです。
よろしくおねがいします。
発生している問題・エラーメッセージ
TypeError Cannot read property 'title' of undefined
該当のソースコード
React
1import React, { useState, useMemo } from "react"; 2 3export default function App() { 4 const initialState = { 5 tasks: [ 6 { 7 id: 1, 8 title: "title", 9 category: 1, 10 text: "" 11 } 12 ], 13 categories: [ 14 { 15 id: 1, 16 title: "未着手" 17 }, 18 { 19 id: 2, 20 title: "進行中" 21 }, 22 { 23 id: 3, 24 title: "完了" 25 } 26 ] 27 }; 28 const [tasks, setTasks] = useState(initialState.tasks); 29 const [categories, setCategories] = useState(initialState.categories); 30 const defaultItem = () => ({ id: 1, title: item, category: 1, text: "" }); 31 const [item, setItem] = useState(""); 32 33 const handleNewitem = (e) => setItem(e.target.value); 34 35 const handleSubmit = (e) => { 36 e.preventDefault(); 37 if (item === "") return; 38 setTasks((tasks) => [...tasks, defaultItem()]); 39 setItem(""); 40 }; 41 42 const handleRemoveItem = (index) => { 43 const newItems = [...tasks]; 44 newItems.splice(index, 1); 45 setTasks(newItems); 46 }; 47 48 //クリックしてcategoryの数値が3になった(完了と表示される)あとにクリックすると1(未着手)の状態に戻る 49 const handleStateIncrease = (index) => { 50 if (index > 3) return; 51 const newTasks = [...tasks]; 52 newTasks[index].category++; 53 setTasks(newTasks); 54 }; 55 56 const [filterQuery, setFilterQuery] = useState({}); 57 58 const filteredTask = useMemo(() => { 59 60 let tmpTasks = tasks; 61 62 tmpTasks = tmpTasks.filter((row) => { 63 if ( 64 filterQuery.category_id && 65 row.category !== parseInt(filterQuery.category_id) 66 ) { 67 return false; 68 } 69 return row; 70 }); 71 72 return tmpTasks; 73 }, [filterQuery, tasks]); 74 75 const handleFilter = (e) => { 76 const { name, value } = e.target; 77 setFilterQuery({ ...filterQuery, [name]: value }); 78 }; 79 80 return ( 81 <div className="wrap"> 82 <div className="input-group"> 83 <form onSubmit={handleSubmit}> 84 <input 85 value={item} 86 placeholder="Enterを押してください" 87 onChange={handleNewitem} 88 /> 89 [追加] 90 </form> 91 </div> 92 <div className="input-group"> 93 <div className="selectbox"></div> 94 </div> 95 96 <table> 97 <thead> 98 <tr> 99 <th>[タイトル]</th> 100 <th>[カテゴリー]</th> 101 </tr> 102 </thead> 103 104 <tbody> 105 {filteredTask.map((task, index) => { 106 return ( 107 <tr key={task.id}> 108 <td> 109 {task.title} 110 </td> 111 <td> 112 <span onClick={() => handleStateIncrease(index)}> 113 {task.category 114 ? categories.find((c) => c.id === task.category).title 115 : ""} 116 </span> 117 </td> 118 <td> 119 <button onClick={() => handleRemoveItem(index)}>削除</button> 120 </td> 121 </tr> 122 ); 123 })} 124 </tbody> 125 </table> 126 </div> 127 ); 128} 129
試したこと
if文を使った条件分岐をさせようとしましたが今度はクリックしても反応しませんでした。
補足情報(FW/ツールのバージョンなど)
OS Mac
node -v
v14.17.0
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/19 09:20
退会済みユーザー
2021/09/19 10:40
2021/09/19 13:52