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

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

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

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

React.js

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

Q&A

解決済

1回答

1317閲覧

stateの配列の要素数が増えた時に再レンダーさせる方法

tomaa

総合スコア84

React Native

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

React.js

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

0グッド

0クリップ

投稿2020/08/05 04:59

編集2020/08/05 05:39

前提・実現したいこと

react nativeを利用してアプリ開発をしています。

コンポーネントを配列で管理し、コンポーネントの数(配列の要素数)が増えた時に、画面を再レンダーさせて、配列の数に応じた表示をさせたいです。

下記のコードをベースにどのように実装すれば良いかご存知の方おりましたら、ご教授いただけないでしょうか?

該当のソースコード

①コンソールチェックは、画面更新時のみ表示され、追加ボタンを押した時は表示されません。

JS

1import React, { useState, useEffect } from "react"; 2import { View, StyleSheet, Text, TouchableOpacity } from "react-native"; 3 4export default function TestListItem() { 5 const [arrayList, setArrayList] = useState([]); 6 7 useEffect(() => { 8 console.log("checked"); //①コンソールチェック 9 }, [arrayList.length]); 10 11 arrayList.push(renderList()); 12 13 function handleMakeNew() { 14 arrayList.push(renderList()); 15 } 16 17 function renderList() { 18 return ( 19 <View style={styles.container}> 20 <View style={styles.list}> 21 <TouchableOpacity 22 onPress={() => { 23 handleMakeNew(); 24 }} 25 style={styles.buttonAdd} 26 > 27 <Text>追加する</Text> 28 </TouchableOpacity> 29 </View> 30 </View> 31 ); 32 } 33 34 return arrayList; 35} 36 37const styles = StyleSheet.create({ 38 container: { 39 padding: 5, 40 justifyContent: "center", 41 backgroundColor: "snow", 42 }, 43 44 list: { 45 width: "100%", 46 backgroundColor: "#ddd", 47 marginBottom: 5, 48 borderRadius: 10, 49 padding: 10, 50 }, 51 52 buttonAdd: { 53 backgroundColor: "orange", 54 width: 80, 55 height: 40, 56 borderRadius: 5, 57 margin: 3, 58 justifyContent: "center", 59 alignItems: "center", 60 alignSelf: "center", 61 }, 62});

試したこと

②の場所に追加ボタンを押した時に、forceUpdate();で更新させようとしてもエラーとなります。

JS

1import React, { useState, useEffect } from "react"; 2import { View, StyleSheet, Text, TouchableOpacity } from "react-native"; 3 4export default function TestListItem() { 5 const [arrayList, setArrayList] = useState([]); 6 7 useEffect(() => { 8 console.log("checked"); 9 }, [arrayList.length]); 10 11 arrayList.push(renderList()); 12 13 function handleMakeNew() { 14 arrayList.push(renderList()); 15 forceUpdate(); //②forceUpdate(); を追加 16 } 17 18 function renderList() { 19 return ( 20 <View style={styles.container}> 21 <View style={styles.list}> 22 <TouchableOpacity 23 onPress={() => { 24 handleMakeNew(); 25 }} 26 style={styles.buttonAdd} 27 > 28 <Text>追加する</Text> 29 </TouchableOpacity> 30 </View> 31 </View> 32 ); 33 } 34 35 return arrayList; 36} 37 38const styles = StyleSheet.create({ 39 container: { 40 padding: 5, 41 justifyContent: "center", 42 backgroundColor: "snow", 43 }, 44 45 list: { 46 width: "100%", 47 backgroundColor: "#ddd", 48 marginBottom: 5, 49 borderRadius: 10, 50 padding: 10, 51 }, 52 53 buttonAdd: { 54 backgroundColor: "orange", 55 width: 80, 56 height: 40, 57 borderRadius: 5, 58 margin: 3, 59 justifyContent: "center", 60 alignItems: "center", 61 alignSelf: "center", 62 }, 63});

エラーメッセージは以下の内容です。

ReferenceError: Can't find variable: forceUpdate

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

node : 12.18.3
react native : 4.10.1
expo : 3.22.3

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

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

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

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

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

wilf

2020/08/05 05:17

エラーが出る場合は、エラーの内容を記載すると解決に近くなるので、記載するようにしましょう。
tomaa

2020/08/05 05:36

ありがとうございます。エラー内容追加し編集しました。
guest

回答1

0

ベストアンサー

state に対して arrayList.push(renderList()) するのと、
ReactNode を state 管理するのはよくありません。

↓count にした例です(React Native じゃないので注意してください。)

export default function TestListItem() { const [count, setCount] = useState(1) useEffect(() => { console.log('checked') //①コンソールチェック }, [count]) function handleMakeNew() { setCount(v => v + 1) console.log(count) } function renderList() { return ( <div> hoge <div> <button onClick={() => { handleMakeNew() console.log(count) }} > 追加する </button> </div> </div> ) } return [...Array(count).keys()].map(i => <renderList key={i} />) }

投稿2020/08/05 06:13

anozon

総合スコア662

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

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

tomaa

2020/08/05 06:34

ご回答いただきありがとうございます。 おかげさまで、希望の動作となりました。 コードの書き方は理解できない所が多いですが、こらから知識を深めたいと思います。
tomaa

2020/08/06 04:15

先日はご回答いただきありがとうございます。 可能であれば、アドバイスをいただきたいのですが、この質問の内容はお陰様で解決できたのですが、`<renderList key={i} />`のコンポーネントにTextInputのコンポーネントを追加すると、うまく入力ができなくなってしまいます。 1文字入力する度に、カーソルを当て直さなければならなく、連続して文字を入力できない状況です。 別の質問として載せていますので、もし可能であればご覧いただけると幸いです。 https://teratail.com/questions/282808
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問