前提・実現したいこと
React Nativeを利用してアプリの開発をしています。
下記の3つの要素が1組となるコンポーネントがあります。
- TextInput
- Button(追加)
- Button(削除)
追加ボタンを押すと、コンポーネントが追加され、削除を押すと削除されます。
追加や削除されるコンポーネントは、配列で管理され、それぞれ入力されたテキストの値は配列の値として管理されます。
削除ボタンが押されると、対象のコンポーネントが削除され、そのコンポーネントは、
- 画面に表示されなくなる
- 配列から要素が削除される
- テキストインプットの枠にはコンポーネントの順番と、配列のindexの順番が一致した値が表示される
という動きになってほしいのですが、3番目の動作がうまくいきません。
例えば、下記のように
- 0番目に→000を入力
- 1番目に→111を入力
- 2番目に→222を入力
した状態で1番目の削除ボタンを押すと、
下記のように
0番目に→000が表示(OK)
1番目に→111が表示(222と表示したい)
となってしまいます。
発生している問題
削除ボタンを押した際に、実際の配列は、左上の確認[]に表示しているように、要素は正しい値を持っていますが、レンダーされる画面は正しい値が表示されません。
予想している原因は、stateで管理している配列が、要素数の変化で状態変化を制御しており、要素自体の変化に対応していない事だと思っています。
下記のコードはイメージですが、このようにuseEffectを利用する事が、対策になるかと考えていますが、実際の実装の方法がわかりません。
そこで、下記のコードのような場合、配列の要素の変化ごとにstateを利用して再レンダーさせる方法を知りたいです。
方法等について、ご存知の方おりましたら、ご教授いただけないでしょうか?
該当のソースコード
JS
1import React, { useState, useEffect } from "react"; 2import { View, Text, Button, TextInput, StyleSheet } from "react-native"; 3 4function Item({ handleInput, handleAdd, handleDelete, index }) { 5 return ( 6 <View style={styles.list}> 7 <Text>{index}</Text> 8 <TextInput 9 style={{ borderWidth: 1 }} 10 onChange={(e) => { 11 handleInput(index, e.nativeEvent.text); 12 console.log(number); //配列の値確認 13 }} 14 ></TextInput> 15 <Button 16 title="追加" 17 onPress={() => { 18 handleAdd(); 19 }} 20 /> 21 <Button 22 title="削除" 23 onPress={() => { 24 handleDelete(index); 25 }} 26 /> 27 </View> 28 ); 29} 30 31export default function TestStateArray() { 32 const [count, setCount] = useState(1); 33 const [number, setNumber] = useState([]); 34 35 // useEffect(() => { 36 // setNumber(number); 37 // }, [number][i]); 38 39 function handleAdd() { 40 setCount((v) => v + 1); 41 } 42 43 function handleDelete(index) { 44 setCount((v) => v - 1); 45 setNumber((v) => { 46 v.splice(index, 1); 47 return v; 48 }); 49 } 50 51 function handleInput(index, text) { 52 setNumber((v) => { 53 v[index] = text; 54 console.log(number); 55 return v; 56 }); 57 } 58 59 return ( 60 <View> 61 <Text>確認{JSON.stringify(number)}</Text> 62 63 {Array.from({ length: count }, (_, i) => ( 64 <Item 65 number={number} 66 handleInput={handleInput} 67 handleAdd={handleAdd} 68 handleDelete={handleDelete} 69 key={i} 70 index={i} 71 /> 72 ))} 73 </View> 74 ); 75} 76 77const styles = StyleSheet.create({ 78 list: { 79 margin: 10, 80 padding: 10, 81 backgroundColor: "#ddd", 82 }, 83}); 84
補足情報(FW/ツールのバージョンなど)
node : 12.18.3
react native : 4.10.1
expo : 3.22.3
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/08/10 14:12