F8app代碼學(xué)習(xí)的要點(diǎn)(3)-button組件

Button組件
路徑:f8app/js/common/Button.js
Button組件很簡單浓利,但是也用到了很多子組件树绩,一個(gè)一個(gè)來看看

 /*f8app/js/common/Button.js*/
  'use strict';
var F8Colors = require('F8Colors');//引入顏色常量
var Image = require('Image');//image組件
var LinearGradient = require('react-native-linear-gradient');//漸變色組件二鳄,github登錄按鈕的樣式
var React = require('React');
var StyleSheet = require('StyleSheet');
var { Text } = require('F8Text'); //f8app包裝的組件,打包了一些和文本有關(guān)的子組件
var TouchableOpacity = require('TouchableOpacity');//相當(dāng)于bootstrap的button組件。
var View = require('View');

class F8Button extends React.Component {
  props: {  //屬性的類型檢測
    type: 'primary' | 'secondary' | 'bordered';
    icon: number;
    caption: string;
    style: any;
    onPress: () => void;
  };

  render() {
    const caption = this.props.caption.toUpperCase();
    let icon;
    //如果傳入圖片的屬性影所,則使用這個(gè)屬性,icon是圖標(biāo)僚碎,caption是按鈕的文字
    if (this.props.icon) {
      icon = <Image source={this.props.icon} style={styles.icon} />;
    }
    let content;
    if (this.props.type === 'primary' || this.props.type === undefined) {
      content = (
        <LinearGradient
          start={[0.5, 1]} end={[1, 1]}
          colors={['#6A6AD5', '#6F86D9']}
          style={[styles.button, styles.primaryButton]}>
          {icon}
          <Text style={[styles.caption, styles.primaryCaption]}>
            {caption}
          </Text>
        </LinearGradient>
      );
    } else {
      var border = this.props.type === 'bordered' && styles.border;
      content = (
        <View style={[styles.button, border]}>
          {icon}
          <Text style={[styles.caption, styles.secondaryCaption]}>
            {caption}
          </Text>
        </View>
      );
    }
    return (
      <TouchableOpacity
        accessibilityTraits="button"
        onPress={this.props.onPress}
        activeOpacity={0.8}
        style={[styles.container, this.props.style]}>
        {content}
      </TouchableOpacity>
    );
  }
}

const HEIGHT = 50;

var styles = StyleSheet.create({
//...看源碼猴娩,此處省略
});

module.exports = F8Button; 

F8Text組件

/*f8app/js/common/F8Text.js*/
'use strict';

import React, {StyleSheet, Dimensions} from 'react-native';
import F8Colors from 'F8Colors';
//封裝text
export function Text({style, ...props}: Object): ReactElement {
  return <React.Text style={[styles.font, style]} {...props} />;
}
//封裝標(biāo)題
export function Heading1({style, ...props}: Object): ReactElement {
  return <React.Text style={[styles.font, styles.h1, style]} {...props} />;
}
//段落內(nèi)容主體
export function Paragraph({style, ...props}: Object): ReactElement {
  return <React.Text style={[styles.font, styles.p, style]} {...props} />;
}
//使用Dimensions組件獲取實(shí)際硬件的寬度
const scale = Dimensions.get('window').width / 375;
//根據(jù)實(shí)際硬件寬度放大得到實(shí)際尺寸的動態(tài)縮放
function normalize(size: number): number {
  return Math.round(scale * size);
}

const styles = StyleSheet.create({
 
  h1: {
    fontSize: normalize(24),  //normalize函數(shù)的使用。
    lineHeight: normalize(27),
    color: F8Colors.darkText,
    fontWeight: 'bold',
    letterSpacing: -1,
  }
  //省略部分代碼
});

TouchableOpacity 組件封裝了ios和android不同的類型

  /*f8app/js/common/F8Touchable.js*/
 'use strict';

import React, {
  TouchableHighlight,
  TouchableNativeFeedback,
  Platform,
} from 'react-native';

function F8TouchableIOS(props: Object): ReactElement {
  return (
    <TouchableHighlight
      accessibilityTraits="button"
      underlayColor="#3C5EAE"
      {...props}
    />
  );
}
//根據(jù)動態(tài)或的的操作系統(tǒng)加載不同的組件
const F8Touchable = Platform.OS === 'android'
  ? TouchableNativeFeedback
  : F8TouchableIOS;

module.exports = F8Touchable;

以上幾個(gè)組件LoginButton組件中使用.
關(guān)鍵的幾個(gè)地方:根據(jù)狀態(tài)加載組件的文字勺阐,es6的異步競爭操作卷中,redux的connect函數(shù)的使用。

/*f8app/js/common/LoginButton.js*/
'use strict';

const React = require('react-native');
const {StyleSheet} = React;
const F8Button = require('F8Button');

const { logInWithFacebook } = require('../actions'); //loginbutton要dispatch的函數(shù)
const {connect} = require('react-redux'); //connect函數(shù)

class LoginButton extends React.Component {
  props: {
    style: any;
    source?: string; // For Analytics
    dispatch: (action: any) => Promise;
    onLoggedIn: ?() => void;
  };
  state: {
    isLoading: boolean;
  };
  _isMounted: boolean;

  constructor() {
    super();
    this.state = { isLoading: false };
  }

  componentDidMount() {
    this._isMounted = true;
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  render() {
//根據(jù)isLoading的狀態(tài)決定加載那個(gè)組件
    if (this.state.isLoading) {
      return (
        <F8Button
          style={[styles.button, this.props.style]}
          caption="Please wait..."
        />
      );
    }

    return (
      <F8Button
        style={[styles.button, this.props.style]}
        icon={require('../login/img/f-logo.png')}
        caption="Log in with Facebook"
        onPress={() => this.logIn()}
      />
    );
  }
//登錄的異步操作
  async logIn() {
    const {dispatch, onLoggedIn} = this.props; //通過connect注入的dispatch和onLOggedIN函數(shù)

    this.setState({isLoading: true});//點(diǎn)擊登錄按鈕渊抽,改變isLoading的狀態(tài)
    try {
      await Promise.race([ //下面兩個(gè)異步函數(shù)式競爭關(guān)系蟆豫,第一個(gè)在1.5秒沒完成就會執(zhí)行超時(shí)函數(shù)tiemout
        dispatch(logInWithFacebook(this.props.source)),//dispatch登錄函數(shù)
        timeout(15000),//超時(shí)函數(shù)
      ]);
    } catch (e) {
      const message = e.message || e;
      if (message !== 'Timed out' && message !== 'Canceled by user') {
        alert(message);
        console.warn(e);
      }
      return;
    } finally {
      this._isMounted && this.setState({isLoading: false});
    }

    onLoggedIn && onLoggedIn();
  }
}

async function timeout(ms: number): Promise {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('Timed out')), ms);
  });
}

var styles = StyleSheet.create({
  button: {
    alignSelf: 'center',
    width: 270,
  },
});
//connect應(yīng)該是redux學(xué)習(xí)的一個(gè)難點(diǎn)和突破點(diǎn),UI組件通過connect
//可以獲取全局的所有的state,redux里面只有一個(gè)state樹懒闷。但是
//LoginButton的狀態(tài)是自己決定的十减,因此沒有注入state
//redux還可接受UI組件的dispatch函數(shù)傳遞的action和相應(yīng)的實(shí)參,
//如果這里的action和redux的actiontype想匹配就就導(dǎo)致相應(yīng)的State的改變愤估。
//這個(gè)組件state應(yīng)該返回登錄的token供其他組件來使用帮辟。
module.exports = connect()(LoginButton);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市灵疮,隨后出現(xiàn)的幾起案子织阅,更是在濱河造成了極大的恐慌,老刑警劉巖震捣,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荔棉,死亡現(xiàn)場離奇詭異闹炉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)润樱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門渣触,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人壹若,你說我怎么就攤上這事嗅钻。” “怎么了店展?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵养篓,是天一觀的道長。 經(jīng)常有香客問我赂蕴,道長柳弄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任概说,我火速辦了婚禮碧注,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘糖赔。我一直安慰自己萍丐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布放典。 她就那樣靜靜地躺著逝变,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奋构。 梳的紋絲不亂的頭發(fā)上骨田,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機(jī)與錄音声怔,去河邊找鬼态贤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛醋火,可吹牛的內(nèi)容都是我干的悠汽。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼芥驳,長吁一口氣:“原來是場噩夢啊……” “哼柿冲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兆旬,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤假抄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宿饱,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熏瞄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谬以。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片强饮。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖为黎,靈堂內(nèi)的尸體忽然破棺而出邮丰,到底是詐尸還是另有隱情,我是刑警寧澤铭乾,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布剪廉,位于F島的核電站,受9級特大地震影響炕檩,放射性物質(zhì)發(fā)生泄漏妈经。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一捧书、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骤星,春花似錦经瓷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至队贱,卻和暖如春色冀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柱嫌。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工锋恬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人编丘。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓与学,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘉抓。 傳聞我的和親對象是個(gè)殘疾皇子索守,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容