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

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

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

HTML5で記述されたモバイルアプリの高速化、およびネイティブアプリライクなUIが作れるフレームワーク。 様々なJavaScriptフレームワークと併せて使用することができます。スマートフォン向けアプリ、Webサイトに必要なアニメーション、UI/UXを実装することが可能になります。

React.js

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

Q&A

解決済

1回答

1646閲覧

react-onsenui の Tabbar で子コンポーネントへ props が渡せません

KentaKonno

総合スコア28

Onsen UI

HTML5で記述されたモバイルアプリの高速化、およびネイティブアプリライクなUIが作れるフレームワーク。 様々なJavaScriptフレームワークと併せて使用することができます。スマートフォン向けアプリ、Webサイトに必要なアニメーション、UI/UXを実装することが可能になります。

React.js

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

0グッド

0クリップ

投稿2018/12/29 06:10

編集2018/12/30 00:44

前提・実現したいこと

構成

親コンポーネント(タブバー描画)
|-- HomePage タプ
`-- SettingsPage タブ

HomePageコンポーネントでのイベント発火で親コンポーネントの state を更新し、それをもう一つの SettingsPageコンポーネントへ props として渡したいのですが渡せません。

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

親コンポーネントのstateは更新されていますが↓
親コンポーネント

タブコンポーネントにはpropsとして渡っていません↓
タブコンポーネント

該当のソースコード

JavaScript

1// App.js 2 3import React, {Component} from 'react'; 4import PropTypes from 'prop-types'; 5import {Page, Tab, Tabbar, Button} from 'react-onsenui'; 6 7import 'onsenui/css/onsenui.css'; 8import 'onsenui/css/onsen-css-components.css'; 9import './App.css'; 10 11// HomePage タブ 12const HomePage = (props) => ( 13 <Page> 14 <Button onClick={props.omikuji}>Click !</Button> 15 </Page> 16); 17HomePage.propTypes = { 18 omikuji: PropTypes.func, 19}; 20 21// SettingsPage タブ 22const SettingsPage = (props) => ( 23 <Page> 24 {props.scores.map((score) => ( 25 <div key={score.created_at}>{score.fortune}</div> 26 ))} 27 </Page> 28); 29SettingsPage.propTypes = { 30 scores: PropTypes.arrayOf( 31 PropTypes.shape({ 32 created_at: PropTypes.instanceOf(Date), 33 fortune: PropTypes.string, 34 }) 35 ), 36}; 37 38// 親コンポーネント 39class App extends Component { 40 state = {scores: []}; 41 scoreItems = []; 42 43 // タブの描画 44 renderTabs = () => { 45 return [ 46 { 47 content: <HomePage key="Home" omikuji={this.handleOnClick} />, 48 tab: <Tab key="Home" label="Home" icon="md-home" />, 49 }, 50 { 51 content: <SettingsPage key="settings" scores={this.state.scores} />, 52 tab: <Tab key="settings" label="Settings" icon="md-settings" />, 53 }, 54 ]; 55 }; 56 57 // HomePage タブのボタンクリックでイベント発火 58 handleOnClick = () => { 59 const fortunes = ['大吉', '吉', '中吉', '小吉', '末吉', '凶', '大凶']; 60 let num = Math.floor(Math.random() * fortunes.length); 61 this.scoreItems.unshift({ 62 fortune: fortunes[num], 63 created_at: new Date(), 64 }); 65 this.setState({scores: this.scoreItems.slice()}); 66 }; 67 68 render() { 69 return <Tabbar renderTabs={this.renderTabs} />; 70 } 71} 72 73export default App; 74

試したこと

・コンストラクタ内の scoreItems 変数を props にすると SettingsPage には渡ります
・しかしそれでも SettingsPage 内の <Page /> では "children: Array[0]" となってしまいます

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

$ node -v
v10.14.2
$ npm -v
6.5.0

create-react-app@2.1.2
react(-dom)@16.7.0
onsenui@2.10.6
react-onsenui@1.11.2

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

ドキュメント<Tabbar /> の使い方を調べてみると、ご質問に挙げられているコードですと、<Tabbar />に与える props が足りないのでは?と思いました。

不足と思われたpropsは、以下2点

  • onPreChange
  • index

です。これらを追加し、また若干修正を入れた App.js が以下です。

JSX

1// App.js 2 3import React, {Component} from 'react'; 4import PropTypes from 'prop-types'; 5import {Page, Tab, Tabbar, Button} from 'react-onsenui'; 6 7import 'onsenui/css/onsenui.css'; 8import 'onsenui/css/onsen-css-components.css'; 9import './App.css'; 10 11// HomePage タブ 12const HomePage = (props) => ( 13 <Page> 14 <Button onClick={props.omikuji}>Click !</Button> 15 </Page> 16); 17HomePage.propTypes = { 18 omikuji: PropTypes.func, 19}; 20 21// SettingsPage タブ 22const SettingsPage = (props) => ( 23 <Page> 24 {props.scores.map((score) => ( 25 <div key={score.created_at}>{score.fortune}</div> 26 ))} 27 </Page> 28); 29SettingsPage.propTypes = { 30 scores: PropTypes.arrayOf( 31 PropTypes.shape({ 32 created_at: PropTypes.instanceOf(Date), 33 fortune: PropTypes.string, 34 }) 35 ), 36}; 37 38const FORTUNES = ['大吉', '吉', '中吉', '小吉', '末吉', '凶', '大凶']; 39 40// 親コンポーネント 41class App extends Component { 42 state = { scores: [], index: 0 }; 43 44 // タブの描画 45 renderTabs = () => { 46 return [ 47 { 48 content: <HomePage key="Home" omikuji={this.handleOnClick} />, 49 tab: <Tab key="Home" label="Home" icon="md-home" />, 50 }, 51 { 52 content: <SettingsPage key="settings" scores={this.state.scores} />, 53 tab: <Tab key="settings" label="Settings" icon="md-settings" />, 54 }, 55 ]; 56 }; 57 58 // HomePage タブのボタンクリックでイベント発火 59 handleOnClick = () => { 60 const num = Math.floor(Math.random() * FORTUNES.length); 61 const newItem = { 62 fortune: FORTUNES[num], 63 created_at: new Date(), 64 }; 65 this.setState({ scores: [ newItem, ...this.state.scores ] }); 66 }; 67 68 render() { 69 return ( 70 <Tabbar 71 renderTabs={this.renderTabs} 72 onPreChange={({ index }) => this.setState({ index })} 73 index={this.state.index} 74 />); 75 } 76} 77 78export default App; 79 80

参考までに、上記と同じ App.js を含む Reactアプリを、以下の GitHubレポジトリに上げました。

上記のレポジトリは、古い順に以下の4つのコミットを含みます。

(1) initial commit

(2) Tabberのprops追加、Appのstateにindex追加

(3) fortunesをクリックされる度に作らないようAppの外に移動

(4) this.scoreItemsを削除

上記コミットで、(1) はご質問に挙げられている App.js をそのままコピペしたもので、次の(2) で、 <Tabbar />に不足と思われたpropsを2点追加しました。これでとりあえず意図通りに動くと思います。(3), (4) は、蛇足ながら、ちょっとしたリファクタ案ですので、採用するかどうかは質問者様にお任せします。

以下の画面キャプチャは、上記のReactアプリを yarn start して、「Click!」 を3回クリックしてから、Settings ページを表示させたところです。

イメージ説明

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

投稿2018/12/30 07:32

jun68ykt

総合スコア9058

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

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

KentaKonno

2018/12/30 20:29

ご回答頂きありがとうございました! 期待通りに動作するようになりました。 またリファクタ案についても大変勉強になりました。 とくに (4) では、いったん配列に格納した上で Array.slice() するのではなく、スプレッド演算子を用いてよりスマートに処理できることを教えていただきました。 重ねてありがとうございました。 良いお年をお迎えください。
jun68ykt

2018/12/30 21:08

解決されたようでよかったです!KentaKonnoさんも良いお年をお迎えください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問