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

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

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

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

React.js

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

Q&A

解決済

1回答

735閲覧

【React Native】this.test()とthis.test.bind(this)の違いとは?

nakamu

総合スコア82

React Native

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

React.js

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

0グッド

1クリップ

投稿2019/09/30 13:06

TouchableHighlightがクリックされるとモーダルが表示されるようにしたくて、
最初onPressの部分をthis.test()としていたのですが、これだとクリックのタイミングではなく
コンポーネントがマウントされた際にモーダルが表示されてしまいました。
その後添付のコードのようにbindの書き方を見つけ実行したところうまくいったのですが、
なぜ最初の書き方だとうまくいかず、bindするとうまくいくのかよくわかりません。

Expo

1class HomeCommunity extends React.Component { 2 componentWillMount() { 3 this.state = { 4 img: '', 5 }; 6 } 7 8 componentDidMount() { 9 this.getImage(this.props); 10 } 11 12 getImage(props) { 13 const storageRef = firebase.storage().ref(); 14 const imgRef = storageRef.child(`communities/${props.community.img8}`); 15 imgRef.getDownloadURL().then((url) => { 16 this.setState({ img: url }); 17 }).catch((error) => { 18 console.log('Error getting document:', error); 19 }); 20 } 21 22 test() { 23 const { modalSwitch } = this.props; 24 modalSwitch(true); 25 } 26 27 render() { 28 const { community, modalSwitch } = this.props; 29 const { img } = this.state; 30 return ( 31 // ここのonPressの箇所が今回の問題 32 <TouchableHighlight onPress={this.test.bind(this)}> 33 <View style={styles.container}> 34 <View style={styles.titleView}> 35 <Text style={styles.title}>{community.name}</Text> 36 </View> 37 <View> 38 <Image style={styles.img} source={{ uri: img }} /> 39 </View> 40 </View> 41 </TouchableHighlight> 42 ); 43 } 44} 45 46const mapStateToProps = () => ({}); 47 48const mapDispatchToProps = (dispatch) => ({ 49 modalSwitch: (bool) => { 50 dispatch({ type: 'MODAL_SWITCH', payload: { bool } }); 51 }, 52}); 53 54const styles = StyleSheet.create({ 55 container: { 56 position: 'relative', 57 width: '100%', 58 height: Dimensions.get('window').height, 59 }, 60 titleView: { 61 position: 'absolute', 62 top: 10, 63 left: 10, 64 width: '100%', 65 height: 300, 66 zIndex: 99, 67 }, 68 title: { 69 color: '#fff', 70 fontSize: 16, 71 fontWeight: 'bold', 72 }, 73 img: { 74 width: '100%', 75 height: Dimensions.get('window').height, 76 }, 77}); 78 79export default connect(mapStateToProps, mapDispatchToProps)(HomeCommunity);

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

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

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

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

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

guest

回答1

0

ベストアンサー

イベントリスナー (test()) における this には、onPress="this.test()" のようなシンプルな呼び出し方をすると、イベントを発火した要素 (<TouchableHighlight />) が強制的に代入されます。これを「thisを束縛する」「thisが束縛される」というような言い方をします。
結果、 const { modalSwitch } = this.props; の部分が <TouchableHighlight />.props のような形になってしまって意図した動きになっていないものと思います。

func.bind(thisObj) は、関数 func を呼び出す際、その呼出先の中における this に何を代入するかを指定しています。
onPress={this.test.bind(this)} の時点での this は自分自身
(HomeCommunityインスタンス) ですね。「自分自身の中の test() を呼び出す、その test() の中における this には自分自身を代入する」というような意味になります。

同様に、 onPress={() => this.test()} とすることもできます。これはアロー関数と呼ばれるもので、 function() { ... }() => { ... } のように短縮して書くことができる記法ですが、アロー関数は「thisを束縛しない」ので、呼び出された先の test() の中の this に強制的に何かが代入されることもなく、無事に自分自身を参照してくれます。

投稿2019/10/01 00:38

thyda.eiqau

総合スコア2982

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

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

nakamu

2019/10/26 18:43 編集

遅くなり大変申し訳ありませんでした! まさかthisがそっちを指してるとは。 大変勉強になりました。ありがとうございます。 > イベントを発火した要素 (<TouchableHighlight />) が強制的に代入されます。これを「thisを束縛する」 「thisが束縛される」というような言い方をします。 > 結果、 const { modalSwitch } = this.props; の部分が <TouchableHighlight />.props のような形になってしまって意図した動きになっていないものと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問