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

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

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

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

React.js

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

Q&A

解決済

1回答

985閲覧

ReactのTextInputコンポーネントでのテキスト入力の挙動がおかしくなる

tomaa

総合スコア84

React Native

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

React.js

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

0グッド

0クリップ

投稿2020/08/05 11:11

編集2020/08/06 06:48

前提・実現したいこと

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

親コンポーネントから子コンポーネントへ、prppsでfunctionを渡して、テキスト入力の動きをさせています。

この際、通常のテキスト入力の方法になりません。
(1文字入力した後、再度カーソルをあてなければ、次のテキストを入力できない)

こちらの問題の解決の方法ご存知の方おりましたら、ご教授いただけないでしょうか?

追記(最初の回答をいただいた後)

最初の回答を頂き下記のようにコードを変更しました。
コンポーネントの追加と、通常どおりの連続した入力ができるようになりました。

しかし、TextInputで入力したテキストがStateに保管されていない状態となってしまっています。
子コンポーネントのコード内の//①コンソールチェックの出力は、Object {}となってしまします。

ちなみに、子コンポーネントで入力した値と、親コンポーネントで利用したいため、子コンポーネントのStateの値は親からpropsで渡しています。

親コンポーネント

JS

1import React, { useState, useEffect } from "react"; 2import { View, StyleSheet } from "react-native"; 3import TestListInputItem from "../components/TestListInputItem"; 4 5export default function TestListScreen() { 6 const [texts, setTexts] = useState({}); 7 8 return ( 9 <View style={styles.container}> 10 <TestListInputItem texts={texts} setTexts={setTexts} /> 11 </View> 12 ); 13} 14 15const styles = StyleSheet.create({ 16 container: { 17 flex: 1, 18 justifyContent: "center", 19 }, 20});

子コンポーネント

JS

1import React, { useState, useEffect } from "react"; 2import { 3 View, 4 StyleSheet, 5 Text, 6 TouchableOpacity, 7 TextInput, 8} from "react-native"; 9 10function Item({ setText, handleMakeNew, i }) { 11 return ( 12 <View style={styles.list}> 13 <Text>{i}</Text> 14 <TextInput 15 style={styles.InputName} 16 onChange={(e) => { 17 setText(i, e.target.value); 18 }} 19 ></TextInput> 20 <TouchableOpacity 21 onPress={() => { 22 handleMakeNew(); 23 }} 24 style={styles.buttonAdd} 25 > 26 <Text>追加する</Text> 27 </TouchableOpacity> 28 </View> 29 ); 30} 31 32export default function TestListInputItem(props) { 33 const [count, setCount] = useState(1); 34 const [texts] = useState(props.texts); 35 36 function handleMakeNew() { 37 setCount((v) => v + 1); 38 console.log(texts);//①コンソールチェック 39 } 40 return ( 41 <View> 42 <Text>{JSON.stringify(texts)}</Text> 43 {[...Array(count).keys()].map((i) => ( 44 <Item 45 handleMakeNew={handleMakeNew} 46 setText={(i, text) => 47 props.setTexts((prev) => ({ ...prev, [i]: text })) 48 } 49 key={i} 50 i={i} 51 /> 52 ))} 53 </View> 54 ); 55} 56 57const styles = StyleSheet.create({ 58 list: { 59 width: "100%", 60 backgroundColor: "#ddd", 61 padding: 10, 62 }, 63 InputName: { 64 borderWidth: 1, 65 height: 40, 66 backgroundColor: "#fff", 67 }, 68 buttonAdd: { 69 backgroundColor: "orange", 70 width: 80, 71 height: 40, 72 margin: 3, 73 justifyContent: "center", 74 alignItems: "center", 75 alignSelf: "center", 76 }, 77});

追記終了

該当のソースコード

親コンポーネント

JS

1import React, { useState, useEffect } from "react"; 2import { View, StyleSheet } from "react-native"; 3import TestListInputItem from "../components/TestListInputItem"; 4 5export default function HomeScreen() { 6 const [name, setName] = useState(""); 7 8 const setInputName = (text) => { 9 setName(text); 10 }; 11 12 return ( 13 <View style={styles.container}> 14 <TestListInputItem name={name} setInputName={setInputName} /> 15 </View> 16 ); 17} 18 19const styles = StyleSheet.create({ 20 container: { 21 flex: 1, 22 justifyContent: "center", 23 }, 24});

子コンポーネント
*仕様の都合で①のコードを変える事はできません。

JS

1import React, { useState } from "react"; 2import { 3 View, 4 StyleSheet, 5 Text, 6 TouchableOpacity, 7 TextInput, 8} from "react-native"; 9 10export default function TestListInputItem(props) { 11 const [count, setCount] = useState(1); 12 13 function handleMakeNew() { 14 setCount((v) => v + 1); 15 } 16 17 function RenderList() { 18 return ( 19 <View style={styles.list}> 20 <TextInput 21 style={styles.InputName} 22 value={String(props.name)} 23 onChangeText={(text) => { 24 props.setInputName(text); 25 }} 26 ></TextInput> 27 <TouchableOpacity 28 onPress={() => { 29 handleMakeNew(); 30 }} 31 style={styles.buttonAdd} 32 > 33 <Text>追加する</Text> 34 </TouchableOpacity> 35 </View> 36 ); 37 } 38 39 return [...Array(count).keys()].map((i) => <RenderList key={i} />); //①仕様の都合でここのコードは変更できない 40} 41 42const styles = StyleSheet.create({ 43 list: { 44 width: "100%", 45 backgroundColor: "#ddd", 46 padding: 10, 47 }, 48 InputName: { 49 borderWidth: 1, 50 height: 40, 51 backgroundColor: "#fff", 52 }, 53 buttonAdd: { 54 backgroundColor: "orange", 55 width: 80, 56 height: 40, 57 margin: 3, 58 justifyContent: "center", 59 alignItems: "center", 60 alignSelf: "center", 61 }, 62}); 63

試したこと

子コンポーネントの①の所でもpropsの要素を持たせても、同じように通常の入力動作になりません。

JS

1return [...Array(count).keys()].map((i) => ( 2 <RenderList key={i} name={props.name} setInputName={props.setInputName} /> 3 ));

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

node : 12.18.3
react native : 4.10.1
expo : 3.22.3

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

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

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

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

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

guest

回答1

0

ベストアンサー

子要素のコンポーネントは外に出したほうがいいですね。
それぞれの input で同じsetInputNameを呼び出してると親コンポーネントで管理できなくなるのでなにか対策が必要かもしれません。

↓例です。
https://codesandbox.io/s/tender-satoshi-37pe3?file=/src/App.js

投稿2020/08/06 05:27

anozon

総合スコア662

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

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

tomaa

2020/08/06 06:53 編集

ご回答ありがとうございます。 ご丁寧に対応していただき、感謝します。 お陰様で、紹介していただいたコードを参考にし、通常どおりの入力、追加コンポーネントそれぞれの表示ができるようになりました。 しかし、入力したテキストを表示できますが、Stateの値として保持する事ができません。 `{JSON.stringify(texts)}`の箇所が`{}`のみ表示となり、textsのstateをコンソールで出力しても値が表示されない状況です。 この場合、子で入力した値と親コンポーネントで取得、利用する事は難しいでしょうか?
anozon

2020/08/06 07:19

ReactNative でも同様にできると思います。 props のバケツリレーのどこかが間違っているのかもしれません。 また、バケツリレー自体を使わずにすむようにするなら react-hooks の useContext やredux などがあります
tomaa

2020/08/06 07:53

何度もすみません。 コメントありがとうございます。 ` onChange={(e) => { setText(i, e.nativeEvent.text); }}` onChangeで受け取るオブジェクトの指定の仕方が違ったみたいで、上の書き方にすると値を受け取れました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問