質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

1回答

1826閲覧

Todoリストの機能で、inputの形式で出力したものを編集できるようにしたい

nto300002

総合スコア1

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/10/24 11:23

前提・実現したいこと

Next.jsでTodoアプリを作成しており、只今Todoリストの編集機能を作成中です。
そのTodoリストの仕様として、Todoのテキストは__<input value={item.text} />__ のような形で出力され、いつでも編集できるというようにしたいです。
しかし、出力された部分をクリックしても編集できるようになりません。これを編集できるようにするにはどのようにすればよいのかわからないので、力を貸していただきたいです。

該当のソースコード

React

1 2import React, { useState } from 'react' 3import { FormLabel, Input ,GridItem, Checkbox, Button } from '@chakra-ui/react' 4import { v4 as uuidv4 } from 'uuid'; 5 6interface Item { 7 id: number; 8 key: number; 9 text: string; 10 checked: boolean; 11} 12 13const InputForm: React.FC = ({ 14 15}) =>{ 16 let keynumber = Number(uuidv4()) 17 const [text, setText] = useState(''); 18 const [items, setItems] = useState<Item[]>([]); 19 20 21 const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => setText(e.target.value) 22 const handleSubmit = (e: React.ChangeEvent<HTMLFormElement>) => { 23 e.preventDefault() 24 if(text === '')return; 25 setItems(items => [ ...items,{id: items.length+1,key: keynumber, text, checked: false }]) 26 setText('') 27 } 28 const handleDeleteItem = (index:number) => { 29 const newItems = [...items] 30 newItems.splice(index,1) 31 setItems(newItems) 32 } 33 34 35 const handleOnEdit = (key: number, text: string) => { 36 37 const newItems = items.map((item) => { 38 if (item.key === key) { 39 item.text = text; 40 } 41 return item; 42 }); 43 44 setItems(newItems); 45 }; 46 47 const handleOnCheck = (key: number, checked: boolean) => { 48 49 const newItems = items.map((item) => { 50 if (item.key === key) { 51 item.checked = !checked; 52 } 53 return item; 54 }); 55 56 setItems(newItems); 57 }; 58 59 60 return ( 61 <> 62 <GridItem colSpan={2}> 63 <form onSubmit={ handleSubmit }> 64 <FormLabel>press Enter</FormLabel> 65 <Input placeholder="Enter" value={text} onChange={(e) => handleChange(e)} /> 66 </form> 67 </GridItem> 68 {items.map((item, index) => { 69 return( 70 <GridItem colSpan={2} > 71 <Checkbox key={item.key} checked={item.checked} 72 onChange={() => handleOnCheck(item.id, item.checked)}> 73 <Input value={item.text} 74 onChange={(e) => handleOnEdit(item.id, e.target.value)} 75 /> 76 <Button colorScheme='pink' size="xs" onClick={() => handleDeleteItem(index)}> 77 delete 78 </Button> 79 </Checkbox> 80 </GridItem> 81 ); 82 })} 83 </> 84 ) 85} 86 87export default InputForm 88

試したこと

chakra-uiを使用していたので、Inputタグをinputに変えてみる

補足情報(FW/ツールのバージョンなど)

@chakra-ui/react 1.6.9
@types/react 17.0.29

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/10/24 11:56

Item に id と key がありますが、id だけで良いのでは。 また、id の型を string にして uuidv4() を指定した方が良いでしょう。 (id を連番にしたくなる気持ちは分かりますが、そんなことをしても有害なだけです。)
guest

回答1

0

直したコード

react

1import React, { useState } from "react"; 2import { FormLabel, Input, GridItem, Checkbox, Button } from "@chakra-ui/react"; 3import { v4 as uuidv4 } from "uuid"; 4 5interface Item { 6 id: number; 7 key: number; 8 text: string; 9 checked: boolean; 10} 11 12const InputForm: React.FC = ({}) => { 13 let keynumber = Number(uuidv4()); 14 const [text, setText] = useState(""); 15 const [items, setItems] = useState<Item[]>([]); 16 17 const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => 18 setText(e.target.value); 19 const handleSubmit = (e: React.ChangeEvent<HTMLFormElement>) => { 20 e.preventDefault(); 21 if (text === "") return; 22 setItems((items) => [ 23 ...items, 24 { id: items.length + 1, key: keynumber, text, checked: false } 25 ]); 26 setText(""); 27 }; 28 const handleDeleteItem = (index: number) => { 29 const newItems = [...items]; 30 newItems.splice(index, 1); 31 setItems(newItems); 32 }; 33 34 const handleOnEdit = (key: number, text: string) => { 35 const newItems = items.map((item) => { 36 console.log(item.id, key); 37 if (item.id === key) { 38 item.text = text; 39 } 40 return item; 41 }); 42 43 setItems(newItems); 44 }; 45 46 const handleOnCheck = (key: number, checked: boolean) => { 47 const newItems = items.map((item) => { 48 if (item.key === key) { 49 item.checked = !checked; 50 } 51 return item; 52 }); 53 54 setItems(newItems); 55 }; 56 57 return ( 58 <> 59 <GridItem colSpan={2}> 60 <form onSubmit={handleSubmit}> 61 <FormLabel>press Enter</FormLabel> 62 <Input 63 placeholder="Enter" 64 value={text} 65 onChange={(e) => handleChange(e)} 66 /> 67 </form> 68 </GridItem> 69 {items.map((item, index) => { 70 return ( 71 <GridItem colSpan={2}> 72 <Checkbox 73 key={item.key} 74 checked={item.checked} 75 onChange={() => handleOnCheck(item.id, item.checked)} 76 /> 77 <Input 78 value={item.text} 79 onChange={(e) => handleOnEdit(item.id, e.target.value)} 80 /> 81 <Button 82 colorScheme="pink" 83 size="xs" 84 onClick={() => handleDeleteItem(index)} 85 > 86 delete 87 </Button> 88 </GridItem> 89 ); 90 })} 91 </> 92 ); 93}; 94 95export default InputForm; 96 97

直して実際に動作するもの

<Checkbox>がInput要素にかぶっていたのとhandleOnEdit()の

typescript

1if (item.id === key) { 2 item.text = text; 3}

typescript

1if (item.key === key) { 2 item.text = text; 3}

item.keyで存在しないプロパティを参照しようとしていたのが原因です

投稿2021/10/26 01:10

編集2021/10/26 01:11
mochi425

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問