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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

Q&A

解決済

2回答

2992閲覧

子コンポーネントで発生したイベントによりstateを更新するときの構文

MakotoKato

総合スコア18

React Native

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

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

0グッド

2クリップ

投稿2018/11/08 03:10

編集2018/11/08 03:19

前提・実現したいこと

react nativeでアプリを制作しております。
基本的なところですが、子のコンポーネントから親のstateを変更したい場合の方法について
お知恵をいただけたらと思います

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

通常子のコンポーネントから親のステートを変更する場合、子のイベント(onClickやonSubmit)で親から渡ってきた関数を
実行する場合が多いかと思いますが、以下のような子のイベントを介さず、通常の関数実行のような形で親のステートを変更することは
可能なのでしょうか

該当のソースコード

便宜上1つのソースコードに親と子のソースコードをまとめさせていただきました。
以下のようなイメージで親のステートを変更したく思います

javascript

1class Parent extends Component { 2constructor(props) { 3 super(props); 4 this.state = { 5 token: null 6 } 7 8updateState(token){ 9 this.setState({token}); 10} 11 12 render() { 13 return ( 14 <Child parentMethod={(token) => this.updateState(token)} /> 15 ); 16 } 17} 18 19class Child extends Component { 20 componentDidMount() { 21 //getToken()は何かのトークンをとってくる関数と仮定 22 let token = getToken() 23 this.props.parentMethod(token); 24 } 25 render() { 26 return null 27 } 28}

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

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

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

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

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

guest

回答2

0

Children がマウントされたときに、親から渡された parentMethod が実行されることによって、Parent の state が変更されて (Parentの)render が計2回呼ばれることが確認できます。

参考文献まで、ご紹介いただき目から鱗の思いです。
ありがとうございます!参考にさせていただきます!

投稿2018/11/23 23:30

MakotoKato

総合スコア18

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

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

0

ベストアンサー

こんにちは。
React&ReduxによるSPA開発の業務に直近の約一年ほど関わっており、現在も継続中の者です。

ご質問に

以下のような

として挙げられているコードについては

  • 子のイベントを介して親のステートを変更している。ただし、そのイベントは(例えば click のような)DOMイベントではなく、ライフサイクルイベントと呼ぶべきイベント

というのが回答になるかなと思います。以下、この回答について説明します。

ご質問のコードで、parentMethod が使われているのは ChildcomponentDidMount() の中の、以下の部分

javascript

1componentDidMount() { 2 //getToken()は何かのトークンをとってくる関数と仮定 3 let token = getToken() 4 this.props.parentMethod(token); 5 }

ですが、これは

  • Childコンポーネントは、自身がマウントされたというイベントを契機に、Parentからpropsで渡される parentMethod を呼び出す。

と言えて、parentMethodは Parentのstateを変えるので、上記は「子のイベントを介して」親のステートを変更するコードとなっています。

componentDidMount() はライフサイクルメソッドのひとつですが、これを「コンポーネントがマウントされたというイベントによって呼ばれるメソッド」というように、イベントという言葉を使って理解しておくことが間違いではないということの根拠となる記事を挙げます。

上記は、Twitterのフォロワー数約2万の技術メンター Tyler McGinnis さんによる投稿ですが、タイトルにあるとおり、"Life Cycle Events" と、イベントという言葉を使っています。

この "ライフサイクルイベント" という言葉を借りれば、

  • 何らかの要素がクリックされたというイベントは DOMイベント 。コンポーネントがマウントされたというイベントはライフサイクルイベント。どちらもイベントであることには変わりない。従って、Parent は Children で発生したイベントによって、stateを変更される。

と、状況を整理することができます。

実際のコードで確認してみますと、以下はReactNativeアプリではなく、Webアプリを作る react-create-app で
作成される App.js を Parent.js にして、ご質問に挙げられているコードに、console.log 出力を何点か加えたものです。

index.js

javascript

1import React from 'react'; 2import ReactDOM from 'react-dom'; 3import Parent from './Parent'; 4 5ReactDOM.render(<Parent />, document.getElementById('root'));

Parent.js

javascript

1import React, { Component } from 'react'; 2 3class Parent extends Component { 4 5 constructor(props) { 6 super(props); 7 this.state = { 8 token: null 9 }; 10 this.renderingCount = 0; 11 } 12 13 updateState(token){ 14 console.log('Parent#updateState: token=' + token); 15 this.setState({token}); 16 } 17 18 render() { 19 this.renderingCount ++; 20 console.log(`renderingCount: ${this.renderingCount}`); 21 console.log(this.state); 22 return ( 23 <Child parentMethod={token => this.updateState(token)} /> 24 ); 25 } 26} 27 28class Child extends Component { 29 30 componentDidMount() { 31 //getToken()は何かのトークンをとってくる関数と仮定 32 //let token = getToken() 33 const token = 'yes'; 34 this.props.parentMethod(token); 35 } 36 37 render() { 38 return <div>This is a child.</div>; 39 } 40} 41 42export default Parent;

以下の画面キャプチャは上記のParentを表示させたところです。

イメージ説明

Children がマウントされたときに、親から渡された parentMethod が実行されることによって、Parent の state が変更されて (Parentの)render が計2回呼ばれることが確認できます。

補足

上記のように初回の表示時に、2回 render() が走ってしまうことに対して、React の公式ドキュメントのcomponentDidMount()の説明に、以下のメモがあります。

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the constructor() instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.

  • 要約: componentDidMount()でsetState()するとrenderを2回呼ぶことになり、それはパフォーマンス上の問題になることがある。とはいえ、componentDidMount()でsetState()しなければならない場合もある。(モーダルやツールチップの表示など)

以上参考になれば幸いです。

投稿2018/11/09 20:45

編集2018/11/11 23:48
jun68ykt

総合スコア9058

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問