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

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

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

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

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

Q&A

解決済

1回答

6334閲覧

stateで管理しているobject内の配列要素の削除方法

tomaa

総合スコア84

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

React.js

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

0グッド

0クリップ

投稿2020/08/18 02:26

前提・実現したいこと

React Nativeを利用してアプリの開発をしています。

下記の3つの要素が1組となるコンポーネントがあります。

  • TextInput
  • Button(追加)
  • Button(削除)

各コンポーネントは配列で管理されており、追加ボタンを押すと、コンポーネントが追加され、削除を押すと削除されます。

発生している問題・エラーメッセージ

コンポーネントの追加と、各コンポーネントでのテキストの入力は期待どおりに機能しています。

しかし、コンポーネントを複数追加した状態で、削除のボタンを押すと、対象のコンポーネントだけではなく、追加した分の全てのコンポーネントが削除されてしまいます。

削除ボタンを押した対象のコンポーネントのみを削除するには、どのようにコードを変更すれば良いでしょうか?

該当のソースコード

親コンポーネント

JS

1import React, { useState } from "react"; 2import { ScrollView } from "react-native"; 3import Items from "../components/Items"; 4 5export default function Screen() { 6 const items = { 7 lists: [""], 8 name: [""], 9 }; 10 11 const [stateItems, setStateItems] = useState(items); 12 13 return ( 14 <ScrollView> 15 <Items stateItems={stateItems} setStateItems={setStateItems} /> 16 </ScrollView> 17 ); 18}

子コンポーネント

JS

1import React, { useState } from "react"; 2import { 3 StyleSheet, 4 View, 5 Text, 6 TextInput, 7 TouchableOpacity, 8} from "react-native"; 9 10function Item({ stateItems, index, handleInputName, handleAdd, handleDelete }) { 11 const [inputValue, setInputValue] = useState(stateItems.name[index]); 12 return ( 13 <View style={styles.list}> 14 <TextInput 15 style={styles.InputName} 16 value={inputValue} 17 onChangeText={(text) => { 18 setInputValue(text); 19 handleInputName(index, text); 20 }} 21 ></TextInput> 22 <TouchableOpacity 23 onPress={() => { 24 handleAdd(); 25 }} 26 style={[styles.buttonDelate, styles.buttonAdd]} 27 > 28 <Text>追加</Text> 29 </TouchableOpacity> 30 <TouchableOpacity 31 onPress={() => { 32 handleDelete(index); 33 }} 34 style={styles.buttonDelate} 35 > 36 <Text>削除</Text> 37 </TouchableOpacity> 38 </View> 39 ); 40} 41 42export default function Items(props) { 43 const stateItems = props.stateItems; 44 const setStateItems = props.setStateItems; 45 46 const handleInputName = (index, text) => { 47 const ret = stateItems.name; 48 ret[index] = text; 49 setStateItems({ 50 ...stateItems, 51 name: ret, 52 }); 53 }; 54 const handleAdd = () => { 55 setStateItems({ 56 ...stateItems, 57 lists: [...stateItems.lists, ""], 58 }); 59 }; 60 const handleDelete = (index) => { 61 setStateItems({ 62 ...stateItems, 63 lists: [...stateItems.lists].splice(index, 1), 64 }); 65 }; 66 67 return ( 68 <View> 69 {stateItems.lists.map((value, i) => ( 70 <Item 71 key={value + i.toString()} 72 index={i} 73 stateItems={stateItems} 74 setStateItems={setStateItems} 75 handleInputName={handleInputName} 76 handleDelete={handleDelete} 77 handleAdd={handleAdd} 78 /> 79 ))} 80 </View> 81 ); 82} 83 84const styles = StyleSheet.create({ 85 list: { 86 width: "100%", 87 backgroundColor: "#ddd", 88 margin: 5, 89 padding: 10, 90 }, 91 InputName: { 92 flex: 1, 93 borderWidth: 1, 94 backgroundColor: "#fff", 95 borderRadius: 5, 96 height: 40, 97 }, 98 buttonDelate: { 99 backgroundColor: "tomato", 100 width: 80, 101 height: 40, 102 borderRadius: 5, 103 margin: 3, 104 justifyContent: "center", 105 alignItems: "center", 106 alignSelf: "center", 107 }, 108 buttonAdd: { 109 backgroundColor: "orange", 110 }, 111}); 112

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

node : 12.18.3
react native : 4.10.1
expo : 3.22.3

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

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

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

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

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

guest

回答1

0

ベストアンサー

javascript

1const handleDelete = (index) => { 2 setStateItems({ 3 ...stateItems, 4 lists: [...stateItems.lists].splice(index, 1), 5 }); 6 };

ここでlistsspliceの結果を入れているからだと思います。
spliceの戻り値は「削除した要素配列」です。

冗長ですが、下記のようにすれば正常に動作すると思います。

javascript

1const handleDelete = (index) => { 2 let l = [...stateItems.lists]; 3 l.splice(index, 1); 4 5 setStateItems({ 6 ...stateItems, 7 lists: l, 8 }); 9 };

投稿2020/08/18 02:31

編集2020/08/18 02:38
nekoniki

総合スコア2409

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

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

tomaa

2020/08/18 02:41

ご回答ありがとうございました。 参考のコードで期待どおりの動作になりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問