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

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

ただいまの
回答率

89.53%

React : props の値によって適用するcssのプロパティを変更したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 827

dwayne_johnson

score 76

状況

reactでwebアプリケーションを作成しています。
CSSの管理はahrpditeというCSSinJSを実現するパッケージを使ってます。

やりたいこと

propsの値により、flexのwidthを変更したいのですが、
「runningTimeが定義されていない」とコンソールに怒られます。

// TvProgram.jsx

import React from 'react';
import { StyleSheet, css } from 'aphrodite';

const styles = StyleSheet.create({
  tvProgramWrap: {
    height: '60%',
    padding: '0 4px', 
    position: 'relative',
    zIndex: '3', 
  },

  tvProgram: {
    height: '100%',
    width: '100%',
    background: 'white',
    borderRadius: '100px',
    boxShadow: '1px 1px 4px rgba(0,0,0,.25)',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'column',
    fontWeight: 'bold',
    fontSize: '.8rem',
  },

  programTime: {
    fontSize: '.7rem', 
    fontWeight: 'normal',
    color: '#4b4b4b',
  },

  p1: {
    flex: '0 0 ' + programWidth ( pt ), 
  },
});

const pt = this.props.runningTime;

function programWidth (time) {
  const min = 11/60;
  const width =  time * min;
  return width.toString() + "rem"; 
}

class TvProgram extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className={css(styles.tvProgramWrap, styles.p1)}>
        <div className={css(styles.tvProgram,)}>
          { this.props.name }<br />
          <span className={css(styles.programTime)}>{ this.props.time }</span>
        </div>
      </div>
    );
  }
}

export default TvProgram;
// TvPrograms.jsx

import React from 'react';
import { StyleSheet, css } from 'aphrodite';
import TvProgram from './TvProgram';

const styles = StyleSheet.create({
// 省略
});

const TvPrograms = () => (
  <div className={css(styles.tvPrograms)}>
    <TvProgram name="ニュース7" time="7:00 ~ 7:30" runningTime={30} />
    <TvProgram name="うたコン" time="7:30 ~ 8:45" runningTime={75} />
    <TvProgram name="ニュース7" time="8:45 ~ 9:00" runningTime={15} />
  </div>
);

export default TvPrograms;


エラー文は以下の通り

TvProgram.jsx:37 Uncaught TypeError: Cannot read property 'runningTime' of undefined
    at Object.defineProperty.value (TvProgram.jsx:37)
    at __webpack_require__ (bootstrap fbd1499fd1e27da32198:19)
    at Object.<anonymous> (TvPrograms.jsx:1)
    at __webpack_require__ (bootstrap fbd1499fd1e27da32198:19)
    at Object.defineProperty.value (TvListings.jsx:1)
    at __webpack_require__ (bootstrap fbd1499fd1e27da32198:19)
    at Object.defineProperty.value (PageOfTvListings.jsx:1)
    at __webpack_require__ (bootstrap fbd1499fd1e27da32198:19)
    at Object.<anonymous> (getPrefixedValue.js:13)
    at __webpack_require__ (bootstrap fbd1499fd1e27da32198:19)


Tvprograms.jsxの中に<TvProgram name="ニュース7" time="7:00 ~ 7:30" runningTime={30} />のようなコンポネントが複数入っている感じです。

恐らくReactにおけるpropsの参照の仕方を深く理解していないことが原因だと思うのですが、Reactの公式ドキュメントを読んだり、いろいろ調べてみても解決方法がよくわからなかったため、こちらで質問させていただきます。

よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • dwayne_johnson

    2018/03/23 18:49

    すみません、ごちゃついてるstylesの部分を省略していました。いろいろ情報不足で申し訳ありません

    キャンセル

  • dwayne_johnson

    2018/03/23 18:50

    JavaScriptのclass周りの理解(というかJavaScriptそのものの理解)が足りていないように思いますので、目下参考書を読んでいる途中ではあるのですが、、

    キャンセル

  • HayatoKamono

    2018/03/23 18:54 編集

    問題の行の前でthisとthis.propsそれぞれをconsole.log()で中身確認したらどうなりますか?その辺を確認すると良いと思います。参照出来ない理由は回答の通りです。

    キャンセル

回答 2

checkベストアンサー

+2

例えばこのrunningTimeをrender以下で文字列として表示させることは可能でした。

それは、対象のコンポーネントの中で参照しているので、期待通りの動きです。constructorの中でも参照出来ると思います。(APIからの取得データをpropsから渡しているなどの場合は別の話として)

const pt = this.props.runningTime

逆にこの行は対象のコンポーネントの外に書かれているので、参照出来なくて当然かと思います。

「runningTimeが定義されていない」とコンソールに怒られます。

エラー文を読み違えていると思います。

cannot read property xxx of undefined はxxxが未定義というよりも、未定義であるもののxxxを読めないというエラーなので、今回の場合は未定義と怒られているのはpropsの方です。propsが未定義の為、必然的にrunningTimeは読めません。未定義と怒られてしまう理由は前述の通りです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

外で定義した関数にpropsを使うことは無理だとわかったので、classで定義した<div>タグに直接インラインでstyle定義することにしました。

import React from 'react';
import { StyleSheet, css } from 'aphrodite';

const styles = StyleSheet.create({
//省略

});

class TvProgram extends React.Component {
  constructor(props) {
    super(props);
    this.width = this.width.bind(this);
    this.flex = this.flex.bind(this);
  }

  width(time) {
  const min = 11/60;
  const width =  time * min;
  return width.toString() + "rem"; 
  }

  flex(time){
    return "0 0 " + this.width(time);
  }

  render() {
    return (
      <div style={{flex: this.flex(this.props.runningTime), height: '60%'}}>
        <div className={css(styles.tvProgramWrap,)}>
          <div className={css(styles.tvProgram,)}>
            { this.props.name }<br />
            <span className={css(styles.programTime)}>{ this.props.time }</span>
          </div>
        </div>
      </div>
    );
  }
}

export default TvProgram;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る