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

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

新規登録して質問してみよう
ただいま回答率
85.46%
React.js

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

Q&A

解決済

1回答

567閲覧

React todoアプリで完了したタスクを移動させたい

Kddikdi

総合スコア3

React.js

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

0グッド

0クリップ

投稿2021/06/26 10:30

to do アプリで、完了したタスクを移動させようとしているのですが、上手くいきません

constructor(props){ super(props); this.state={ value:'', todoList:[], completeList:[], } } onChange(event){ this.setState({ value: event.target.value, }) } add(){ this.setState({ todoList: this.state.todoList.concat(this.state.value), value:'', }) } delete(idx){ const value = this.state.todoList; value.splice(idx,1); this.setState({todoList: value}); } complete(idx){ const value = this.state.todoList; const CompleteTodo=this.state.todoList; value.splice(idx,1); this.setState({todoList: value}); this.setState({completeList:CompleteTodo}); } render() { const todoListNode= this.state.todoList.map((todo,idx)=>{ return <li key={idx}>     {todo}     <button onClick={()=>{this.delete(idx)}}>削除</button>     <button onClick={()=>{this.complete(idx)}}>完了</button>    </li> }) const CompleteListNode=this.state.completeList.map((todo,idx)=>{ return <li key={idx}>     {todo}    </li> }) return ( <div> <input type="text" value={this.state.value} onChange={(event)=>{this.onChange(event)}} required="required" /> <button onClick={()=>{this.add()}}>保存</button> <ul> {todoListNode} </ul> <h2>完了</h2> <ul> {CompleteListNode} </ul> </div> ); } }
complete(idx){ const value = this.state.todoList; const CompleteTodo=this.state.todoList; value.splice(idx,1); this.setState({todoList: value}); this.setState({completeList:CompleteTodo}); }

上のcomplete内の書き方がおかしいのではないかと思って試行錯誤しているのですが、エラーしか出ないので困っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

この原因と直接関係あるかはわかりませんが、reactではprops/stateは基本的にイミュータブルである必要があり、これを守らないとバグが発生する確率が上がったりundo機能を実装しようとした時に困ったりします。

イミュータブルとは不変という意味で、例えば配列であれば以下のように破壊的な変更をするとarr1だけでなくarr2も変わってしまいます。
こうならないために値を追加/削除/上書きしたい時にはarr3のように新しい配列を作る必要があります。
ここで使用しているスプレッド構文については以下のリンクを参照するか検索してください。
Arrayだとconcatのようなものです。

スプレッド構文 - JavaScript | MDN

スプレッド構文と似てるけど別物なやつがあります。混同しがちなので存在だけ知らせておきます。
分割代入 - JavaScript | MDN

js

1const arr1 = [1, 2, 3]; 2const arr2 = arr1; 3const arr3 = [...arr1]; 4arr1.push(4); 5console.log(arr1); // [1, 2, 3, 4] 6console.log(arr2); // [1, 2, 3, 4] 7console.log(arr3); // [1, 2, 3]

本題のcompleteですが、completeListtodoListで上書きしてしまっているためでしょう。
deletecompleteList版のaddを組み合わせることでできると思います。

addに関しては元のコードでもできますが、コードを統一するためにスプレッド構文を使用しています。

js

1add() { 2 this.setState({ 3 todoList: [...this.state.todoList, this.state.value], 4 value: '', 5 }); 6} 7delete(idx) { 8 const todoList = [...this.state.todoList]; 9 todoList.splice(idx, 1); 10 this.setState({ todoList }); 11} 12complete(idx) { 13 const todoList = [...this.state.todoList]; 14 const [completeTodo] = todoList.splice(idx, 1); 15 this.setState({ 16 todoList, 17 completeList: [...this.state.completeList, completeTodo], 18 }); 19}

投稿2021/06/27 09:47

編集2021/06/27 10:14
ka2obushi

総合スコア173

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

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

Kddikdi

2021/06/29 05:28

返事が遅くなり、申し訳ありません。 詳しく教えていただき本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問