Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
React Native Begineer Tutorial
Search
Avon
August 18, 2018
Programming
110
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React Native Begineer Tutorial
React Native 入門實作課程 ppt
Avon
August 18, 2018
Other Decks in Programming
See All in Programming
UPDATE をやめる — EF Core でマスタをバージョン管理する
panda728
PRO
0
1k
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
310
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
100
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
370
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
330
カツオ、ご期待ください
suneo3476
0
120
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
350
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.2k
アクセシビリティから考える情報設計
high_g_engineer
0
430
Heart of Swift Concurrency
koher
0
1.1k
MVNOの申込からeSIM開通までをiOSアプリでつなぐ- 本人確認・MNP・通信事業者基盤をまたぐ実装
satotakeshi
0
510
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
320
Featured
See All Featured
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
560
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
How STYLIGHT went responsive
nonsquared
100
6.3k
The agentic SEO stack - context over prompts
schlessera
0
940
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
450
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
340
Skip the Path - Find Your Career Trail
mkilby
1
240
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
530
エンジニアに許された特別な時間の終わり
watany
109
250k
Making the Leap to Tech Lead
cromwellryan
135
10k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Transcript
React Native 入⾨門實作課 Avon x APP Girls
成功⼤大學資源⼯工程學系 清華⼤大學動⼒力力機械研究所 ⾃自學程式 女⼈人迷 Hackathon冠軍-智慧法律律APP 台科X政⼤大 Hackathon亞軍-物聯聯網鋼琴 台⼤大 Hackathon企業獎及⼈人氣獎-fb尋找⼿手機/⼈人臉辨識 APP
Girls 創辦⼈人 印氪股份有限公司接案iOS軟體⼯工程師 達暉資訊科技有限公司iOS軟體⼯工程師 Uitox象網智慧科技有限公司APP軟體⼯工程師 天堂遊戲有限公司APP軟體⼯工程師 雅⽅方 Avon
APP Girls APP Girls aims to give tools for girls
and women to build their ideas. 希望不斷推廣⽽而有更更多女⽣生⼀一同透過交流學習,⼀一起 了了解程式開發並能互相切磋,歡迎對程式語⾔言有興趣 的⼀一起加入!
堅持 ,不要臉,堅持不要臉 • 結交⼀一群有相同⽬目標的戰友 • 透過⾃自⼰己有興趣的mini project來來練功 • 適時給⾃自⼰己⼀一點獎勵 •
參參加⿊黑客松吧! 給開發新⼿手的四點建議 下⾺馬親⾃自寫程式^___^
⼤大綱 react native 介紹 react native 基本使⽤用範例例 利利⽤用react-native 快速建立react native專案
執⾏行行APP到iOS&Android雙平台上 VSCode常⽤用功能介紹 專案架構講解 元件基本架構規則 必須熟悉語法寶典 state介紹 專案時間: 利利⽤用react native做出⼀一個密碼判斷 State v.s. Props ⾃自製元件 react-navigation教學 專案時間: 套⽤用react-navigation做各種換⾴頁 專案時間: 套⽤用react-navigation並⾃自製data列列表 做Notice Cart Storage儲存⼯工具 redux數據流框架 Storage v.s. redux ⼩小練習時間 API介紹 PostMan⼯工具 串串接API教學 專案時間: Notice Cart + API 專案實作:我的收藏 Part1 初探react native 熟悉語法架構 Part2 加強必備戰⼒力力 熟悉套件&數據流 Part3 串串接後台不可或缺 熟悉串串接API與實作
2015 年年 3 ⽉月份, Facebook 開放了了 React Native 的原始碼,這是 ⼀一個能夠讓你利利⽤用
JavaScript 建立原⽣生 iOS 及 Android App 的框 架,它已經在世界各地流⾏行行的移動App中廣泛應⽤用,例例如Facebook, Bloomberg, Skype, Instagram和Uber eat。 React Native 「只需學習⼀一次,到處皆可實作」( Learn Once, Write Anywhere ) 學好⼀一套技能,然後運⽤用這套技能來來建構多種平台的 App
React Native 特點 PhoneGap 之類的框架 將網⾴頁內容包裝成 WebView ,形成 UI 元素,看起來來其實跟原⽣生的
有些不⼀一樣 —>基於HTML, CSS,直接使⽤用HTML渲染,⼤大量量使⽤用DOM,很耗性能 React Native 使⽤用 iOS 或 Android 原⽣生⽀支援的 JavaScript 元件,因此打造出來來的 App 就跟原⽣生的沒有兩兩樣。 ex: 代替web組件’div’和’span' —> 基本上就是⽤用原⽣生組件’View’和’Text' —>基於javascript 即時編譯,運⾏行行效率比較⾼高,⽽而且此框架⽤用 Virtual DOM渲染
React Native 特點 Virtual DOM React-Native在JavaScript中抽像操作系統原⽣生的UI組件 ⾼高效機制,判斷新舊狀狀態,即可知道是哪個DOM發⽣生變化, 有更更動,才會更更改渲染,不⽤用每次重繪內容. 通過不同的渲染引擎⽣生成不同平台下的UI
建立初始專案
利利⽤用 react-native 快速建立 react native 專案 npm install -g react-native-cli
(cli = command line interface) 開專案: react-native init AwesomeProject cd AwesomeProject For iOS: react-native run-ios (或是打開資料夾內ios/AwesomeProject.xcodeproj,並點擊Run按鈕。) Tips: 每次修改好程式碼,只要 Cmd+R 就可以reload 除錯⼯工具:’Cmd+D' or shake for dev menu,就會有menu選單跑出來來
利利⽤用 react-native 快速建立 react native 專案 For Android: A. 環境參參數設置
(~/ =>就是路路徑 /Users/使⽤用者名稱/) 在終端下使⽤用vi ~/.bash_profile (命令創建或編輯 (按o 代表換⾏行行模式 打好第⼆二⾏行行後 esc 跳出後 再:wq 儲存離開)) export ANDROID_HOME=~/Library/Android/sdk export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools 執⾏行行source ~/.bash_profile B. 要執⾏行行以前 1. 先開啟android studio 2. 點選“Open an existing Android Studio project”,打開專案內的android資料夾 3. 法⼀一:先打開模擬器,然後終端機react-native run-android 法⼆二: 1. npm start 2. 打開android studio內的斧頭 3. 按⼀一下三⾓角形run (會⾃自動請你打開模擬器) Tips: 按兩兩下R鍵,就可以重新整理理模擬器 command+m,就可以跑出選單(和iOS是 command + d 是⼀一樣的意思) 就可以選擇 Debug JS Remotely http://localhost:8081/debugger-ui/
專案架構說明 講解資料夾內檔案
None
android 原⽣生程式碼 ios 原⽣生程式碼 此App的進入點,也就是開始執⾏行行的地⽅方 整個專案的路路由在這裏匯入 專案依賴管理理檔案 安裝⽬目錄,套件放置區 專案說明,主要給原⽣生 app
打包⽤用,包括專案名稱和⼿手機桌⾯面展⽰示名稱 babel的配置檔案,React Native預設使⽤用babel編譯JavaScript程式碼 以前舊版建立專案時,會⾃自動⽣生成 index.ios.js & index.android.js 但新版只有index.js,並把App.js匯入 到index.js
import 可以使物件屬性在整個檔案的範圍內都可以被參參照到 export 匯出,讓別個檔案使⽤用 stylesheet ⽤用於視圖內容的樣式,主要使⽤用 CSS(Cascading Style Sheets,串串接樣式表)來來設定 App
的 UI 樣式 src: source code 通常會⾃自⾏行行建立 src ⼤大資料夾 (作為App應⽤用Javascript部分所有程式碼和資源的根⽬目錄,放置所有原始的 react native 程式碼) 補充
專案內元件基本架構規則
建構component組件基本三步驟 1. import 模組, 套件 2. 建立樣式表(StyleSheet) 3. class建構版⾯面樣式 import
React, { Component } from 'react'; export default class App extends Component { state = { name: '', validCode: '', clickButton: false } changeName = () => { // this.setState({ name: 'avon' }) this.state.name === 'avon' ? this.setState({ name: '歡迎回來來' }) : this.setState({ name: 'avon' }) } render() { return ( <View style={styles.container}> <Text style={styles.welcome}>Welcome to React Native!</Text> <Text style={styles.instructions}>Hello! {this.state.name}</Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', } }); 初始化state function執⾏行行 渲染
import { StyleSheet, } from 'react-native'; var styles = StyleSheet.create({
container: { paddingTop: 10, backgroundColor: '#b5b5b5', justifyContent: 'center', alignItems: 'center', height: 100 }, red: { color: 'red', }, blue: { fontWeight: 'bold', fontSize: 60, color: ‘blue' }, }); … <View style={styles.container}> <Text style={styles.blue} > hello </Text> <Text style={[styles.blue, styles.red]}> Good Luck </Text> </View > // StyleSheet.create來來集中定義組件的樣式 // CSS中的“層疊”做法 樣式(StyleSheet),多個樣式管理理
開始Coding吧!
✦ 新增⼀一個state 在渲染的JSX內使⽤用{this.state.xxx}來來讀取 ✦ 新增⼀一個funtion 把剛才按鈕內使⽤用的this.setState({xxx}) ⽤用此function包起來來 ✦ 新增⼀一個按鈕來來觸發動作 裡⾯面使⽤用this.setState({xxx})來來改變值
p.s. 補充: 三元運算判斷 <Button title='Click Me' onPress={( ) => this.setState({ name: 'baby' })}/> changeName = ( ) => { } <Button title='Click Me' onPress={( ) => this.changeName( )}/> state初成熟...
✓ state語法 初始化: state = { name:' ', age:18} 讀取:
{this.state.name} 存入: this.setState({ name: ‘avon' }) ✓ function 不帶變數: aaa = ( ) => { } 套⽤用: ( )=>this.aaa( ) 帶變數: aaa = (xxx) => { } 套⽤用: (arg) => this.aaa(arg) ✓ tag內加入參參數 駝峰式⼩小寫 ex: ✓ style寫法 在直接寫在tag內 寫在styleSheet內再引⽤用到tag內 ✓ command標註 // or /* */ or 在render內{/* */} ✓ 元件⼀一定要⼤大寫(⾃自製元件也⼀一樣) <Text style={styles.welcome}>成功</Text> <Text style={{ color: 'green' }}>成功</Text> const styles = StyleSheet.create({ welcome: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', } }); <Button title='Click Me' onPress={( ) => this.setState({ name: 'baby' })}/> 必須熟悉的常⽤用⽤用法寶典
export default class App extends Component { state = {
validCode: '', clickButton: false } getNumber = () => { if (this.state.validCode === '1234') { return ( <Text style={{ color: 'green' }}>輸入成功</Text>) } else { return (<Text style={{ color: 'orange' }}>請輸入密碼</Text>) } } render() { return ( <View style={styles.container}> {/* 輸入⽂文字 */} <TextInput maxLength={4} style={{ height: 50, width: 300, borderRadius: 0, borderColor: 'darkgray', backgroundColor: 'white', fontSize: 28, textAlign: 'center' }} onChangeText={(text) => this.setState({ validCode: text })} keyboardType={"numeric"} value={this.state.validCode} /> {/* 法⼀一:輸入⽂文字,即時判斷 */} {this.state.validCode === '1234' ? <Text style={{ color: 'blue' }}>輸入成功</Text> : <Text style={{ color: 'red' }}>請輸入密碼</Text>} {/* 法⼆二:輸入⽂文字,即時判斷,⽤用function包起來來 */} {this.getNumber()} </View > ); } } 專案實作:密碼判斷 practice project
⽜牛⼑刀⼩小試1.:即時顯⽰示輸入的號碼
⽜牛⼑刀⼩小試2.:如何輸入⽂文字,按鈕後判斷?
恭喜學會⽤用state & setState 更更改元件資料!
⾃自製元件
ex: Button <TouchableOpacity onPress={() => this.changeName()}> <Text>Click</Text> </TouchableOpacity> <MyButton title={'Click'}
onPress={()=>this.changeName()} /> 我想要呈現的樣⼦子...
新增元件 MyButton.js (⼦子) Import 需要的元件 render ⾃自製button export ⾃自製button import
{ TouchableOpacity, Text,} from 'react-native'; class MyButton extends Component { render() { return ( <TouchableOpacity onPress={this.props.onPress} > <Text>{this.props.title}</Text> </TouchableOpacity> ) } } <MyButton title={'Click'} onPress={()=>this.changeName()} /> App.js(⽗父) export default MyButton import MyButton from ‘./MyButton'
Props v.s. State 元件溝通⽅方式 同⼀一元件內的狀狀態管理理 ⽗父⼦子元件間的狀狀態管理理
⽜牛⼑刀⼩小試:如何想要設定style? <MyButton backgroundColor={'red'} color={'yellow'} title={'Next'} onPress={this.changeName} /> 傳遞backgroundColor & 字的顏⾊色?
補充:⾃自製元件-屬性 Prop types import PropTypes from 'prop-types'; MyButton.propTypes = {
title: PropTypes.string.isRequired, color: PropTypes.string, backgroundColor: PropTypes.string, borderRadius: PropTypes.number, onPress: PropTypes.func, }; MyButton.defaultProps = { color: 'white', backgroundColor: 'black', onPress: null, borderRadius: 5, };
專案實作:元件套件換⾴頁 practice project
專案實作:元件套件換⾴頁 practice project tab換⾴頁: 參參考https://reactnavigation.org/docs/en/tab-based-navigation.html 在程式碼最上⽅方“引入套件” import { createBottomTabNavigator, }
from 'react-navigation'; nav bar換⾴頁: 參參考https://reactnavigation.org/docs/en/stack-navigator.html#docsNav 在程式碼最上⽅方“引入套件” import { createStackNavigator, } from 'react-navigation'; 學習換⾴頁-套⽤用套件React-navigation 安裝:npm install --save react-navigation
Tab換⾴頁 const App = createBottomTabNavigator( { Home: { screen: HomeScreen
}, Profile: { screen: ProfileScreen }, }, // add custom bottom tabs { navigationOptions: ({ navigation }) => ({ tabBarIcon: ({ tintColor }) => { const { routeName } = navigation.state; let iconName; if (routeName === 'Home') { iconName = 'ios-trophy' } else if (routeName === 'Profile') { iconName = 'ios-options' } return <Ionicons name={iconName} size={25} color={tintColor} /> }, }), tabBarOptions: { activeTintColor: 'tomato', inactiveTintColor: 'gray', }, } ); export default App 設定客製化參參數 import HomeScreen from './src/screens/HomeScreen' import ProfileScreen from './src/screens/ProfileScreen' import需要有Tab的⾴頁⾯面 ⽤用createBottomTabNavigator包起來來
Nav bar換⾴頁 ⽤用createStackNavigator包起來來 設定客製化參參數 import HomeMainScreen from './HomeMainScreen' import HomeDetailScreen
from './HomeDetailScreen' const HomeScreen = createStackNavigator( { HomeMain: { screen: HomeMainScreen, navigationOptions: () => ({ title: '這是上⽅方title', headerBackTitle: '返回', }), }, HomeDetail: { screen: HomeDetailScreen }, } ); import需要有Tab的⾴頁⾯面 export default HomeScreen
進階: tab & nav bar的結合?
思考流程... 如果要有tab 必須把⾴頁⾯面包進createBottomTabNavigator裡⾯面... 如果要有nav bar 也必須把⾴頁⾯面包進createStackNavigator裡⾯面...
Tab Home Profile HomeMain Detail HomeMain Detail createBottomTabNavigator createStackNavigator createStackNavigator
架構...
const HomeStack = createStackNavigator({ Home: { screen: HomeScreen, navigationOptions: ()
=> ({ title: 'Home title', headerBackTitle: '返回', }), }, HomeDetail: { screen: HomeDetailScreen } }); const ProfileStack = createStackNavigator({ Profile: { screen: ProfileScreen, navigationOptions: () => ({ title: 'Profile title', headerBackTitle: '返回', }), }, HomeDetail: { screen: HomeDetailScreen } }); const App = createBottomTabNavigator( { Home: HomeStack, Profile: ProfileStack, }, // add custom bottom tabs … App.js
不同⾴頁⾯面間的傳值...
this.props.navigation.navigate('HomeDetail', { name: ‘avon' }) render() { const name =
this.props.navigation.getParam('name', 'default value'); return ( … <Text>{name}</Text> … ); } HomeScreen.js HomeDetailScreen.js 換⾴頁+傳變數給內⾴頁 內⾴頁拿到變數呈現
this.props.navigation.navigate('HomeDetail', { name: ‘avon’, function: arg=> this.changeFood(arg) }) render() {
return ( … <Button title="Get Food" onPress={() => this.props.navigation.getParam(‘function')('apple')} /> … ); } HomeScreen.js HomeDetailScreen.js 傳function給內⾴頁,等內⾴頁拿變數傳回來來 內⾴頁拿到function並且回傳參參數 changeFood = (foodGet) => { this.setState({ food: foodGet }) }
專案實作:結合套件換⾴頁+⾃自製列列表 Notice Cart project
Data var FAKE_DATA = [ { notice: '恭喜您!達成環島100次', date: '2018/08/01
14:00', }, { notice: '您的會員⾝身份認證,已審核通過!', date: '2018/08/02 12:00', }, { notice: '撥款通知:本公司已將款項$123456撥入您的指定銀⾏行行帳⼾戶.', date: '2018/08/05 12:30', } … ]
列列表 ListView state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1,
row2) => row1 !== row2 }) } componentDidMount() { var books = FAKE_DATA this.setState({ dataSource: this.state.dataSource.cloneWithRows(books) }) } render() { return ( <View> <ListView dataSource={this.state.dataSource} renderRow={arg => this.renderBook(arg)} style={styles.listView} /> </View> ) }
renderBook = (cases) => { return ( <TouchableHighlight onPress={() =>
this.showNoticeDetail(cases)}> <View> <View style={styles.MainView}> <Image source={{ uri: 'https://pic.pimg.tw/cc1895/1431185098-1614666523.jpg' }} style={styles.thumbnail} /> <View style={{ flex: 1 }}> <Text ellipsizeMode='tail' numberOfLines={3} style={{ color: 'black', fontSize: 15, marginTop: 8 }} >{cases.notice}</Text> <Text ellipsizeMode='tail' numberOfLines={3} style={{ marginTop: 8, fontSize: 13, marginBottom: 8 }} >{cases.date}</Text> </View> <Image style={styles.image} source={require('../img/ic_arrow_right.png')} /> </View> <View style={styles.separator} /> </View> </TouchableHighlight> ) } 列列表 ListView
showNoticeDetail(cases) { this.props.navigation.navigate('HomeDetail', { passProps: cases, }) } 傳遞資料 const
passProps = this.props.navigation.getParam('passProps', 'some default value'); … <Text>{passProps.notice}</Text> …
運⾏行行 unmount props changed shouldComponentUpdate true false state changed
Life Cycle Demo
儲存資料的好⼯工具:AsyncStorage 常拿來來結合儲存key or token (判定登入不重複), 個⼈人資料(id, account number…) 類似瀏覽器的Cookie 唯⼀一官⽅方⽀支援的儲存⽅方式
AsyncStorage.getItem(key) AsyncStorage.setItem(key, value) 存入 讀取
AsyncStorage 結合 async await AsyncStorage: 簡單的、異異步的、持久化的Key-Value存儲系統 —> 處理理異異步(非同步)的救星: async(非同步) await(等待)
等待這段函式完成後,在往下繼續執⾏行行 備註:async await 也常⽤用來來解決callback hell的問題,讓程式碼易易讀性更更⾼高,更更簡潔
AsyncStorage 結合 try catch 需要Error handling 錯誤處理理(捕獲錯誤): 錯誤的接收執⾏行行動作—> catch( )
Await 如果有錯誤發⽣生,只會默默地拋出錯誤 ... 後⾯面的程式碼就無法執⾏行行!
Demo
react-redux數據流框架 為何⽤用redux redux: ⼀一個狀狀態容器 單向數據流,外部組件難以獲取內部組件的數據。 我們想要⼀一個全域變數(全域的state)
react-redux數據流框架 Redux data flow 1. 2. 3.
react-redux數據流框架 加入redux 安裝: npm install --save redux npm install --save
react-redux 新增檔案: 在src內新增資料夾redux, 裡⾯面再新增三個檔案: action.js, reducer.js, store.js
react-redux數據流框架 設置redux action.js export const ADD_TO_COUNTER = 'ADD_TO_COUNTER' export function
addToCounter(newName) { return { type: ADD_TO_COUNTER, payload: { newName: newName }, } } import { ADD_TO_COUNTER } from './action' const initialState = { newName: 'Avon' } export default function reducer(state = initialState, action) { switch (action.type) { case ADD_TO_COUNTER: return { ...state, newName: action.payload.newName } default: return state } reducer.js 定義action名稱&動作 (action creator) 是否要傳入參參數 action名稱規則:以全⼤大寫表⽰示 監聽action,並依照不同動 作來來更更新狀狀態 listens to actions and modifies the state 引入action 定義初始狀狀態 傳入初始狀狀態&action 會依據不同的action來來更更新狀狀態 標⽰示動作類型
react-redux數據流框架 設置redux store.js import reducer from './reducer' import { createStore
} from 'redux' export default function configureStore() { let store = createStore( reducer ) return store } import { Provider } from 'react-redux' import configureStore from './src/redux/store' const store = configureStore() const MyApp = () => ( <Provider store={store}> <App /> </Provider> ) // AppRegistry.registerComponent(appName, () => App); AppRegistry.registerComponent(appName, () => MyApp) index.js 引入reducer 利利⽤用creactStore創建store 引入reducer到store,並讓之後 app進入點可以引入這個store connects the reducer to the store 新增兩兩⾏行行 引入store和Provider組件 利利⽤用Provider引入store (Provider把store當成參參數往下傳) 改成下⾯面這⾏行行
react-redux數據流框架 存入&讀取 ProfileScreen.js import { connect } from 'react-redux' import
{ addToCounter } from ‘../redux/action' … <Text>{this.props.newName}</Text> <Button onPress={() => this.props.addToCounter(this.state.name)} title='設定名字2' /> … const mapStateToProps = (state) => { return { newName: state.newName } } const mapDispatchToProps = (dispatch) => { return { // 法⼀一 // addToCounter: (name) => { // dispatch({ type: 'ADD_TO_COUNTER', payload: { newName: name } }) // } // 法⼆二 addToCounter: (name) => dispatch(addToCounter(name)) } } export default connect(mapStateToProps, mapDispatchToProps)(ProfileScreen) 新增兩兩⾏行行 引入connect和動作 讀取:⽤用this.props讀取變數 讀取: 把全域的state “state.newName” 轉變成props, 讓這⾴頁ProfileScreen⽤用this.props.newName來來讀取 觸發動作: 利利⽤用dispatch來來呼叫執⾏行行動作(action),就會觸發 reducer來來返回新的state,connect即會監聽到state 的變化,合併回props action export default 改成此⾏行行 利利⽤用connect來來接收Provider傳入的store, 並把全域參參數state變成props拿來來給此component使⽤用
Storage v.s. redux
專案實作:串串接API My_Book_List_api 在實作專案之前...
什什麼是API? Application Programming Interface(應⽤用程式介⾯面) 定義很廣泛... 系統溝通的介⾯面 原本服務的延伸 互動的橋樑 資料的交換 ex:
Google Maps API, Azure, KKBOX, …
串串接API RESTful API (串串接api的其中⼀一個規矩寫法) HTTP protocol: GET/POST/PUT/DELETE 補充:另外也可以使⽤用 HTTP status
code 來來代表該資源的狀狀態 Ex: 200 (成功), 404(失敗), 也可以⾃自訂
GET 取資料 POST 傳資料 串串接API 最常⽤用的兩兩種⽅方式:
postman⼯工具教學 下載:https://www.getpostman.com/
專案實作:串串接API My_Book_List_api
備註:⼀一定要放到 componentDidMount const host = 'https://njapp.uitoxbeta.com/app'; const url = `${host}${route}`;
var params = { "articleId": this._deckSwiper._root.state.selectedItem._id, "userId": this.state.userId, } const options = { method: 'POST', headers: { Accept: 'application/json', authorization: token, 'Content-Type': 'application/json', }, body: (params ? JSON.stringify(params) : null), }; 簡單⽤用法:fetch('Put API Request URL Here', { method: 'get'}) 常⽤用⽅方法:fetch(url, options) Fetch API 常⽤用基本⽅方法
const REQUEST_URL = 'https://www.googleapis.com/books/v1/volumes?q=subject:fiction' fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) =>
{ this.setState({ dataSource: this.state.dataSource.cloneWithRows(responseData.items) }); }) .catch((err) => { console.log('error') }) Fetch API 常⽤用基本⽅方法
專案實作:結合storage加入到我的最愛or 我的收藏 My_Book_List_api_storage
有幾本被勾選? 被勾選到的書是哪些? 存到storage 新增新的Array, 有被勾選就放進來來
state ={ … ds:[ ] } fetch … this.setState({ dataSource:
this.state.dataSource.cloneWithRows(responseData.items), ds:responseData.items }); … <TouchableHighlight onPress={() => this.pressRow(cases)}> {cases.addToMyLists === true ? <Image style={styles.imageCheck} source={require('../img/square_check.png')} /> : <Image style={styles.imageCheck} source={require('../img/square_non_check.png')} />} </TouchableHighlight> … 讀取data+新增勾選按鈕
pressRow = (cases) => { const newDatas = this.state.ds.map(a =>
{ let copyA = { ...a }; if (copyA.id === cases.id) { copyA.addToMyLists = !copyA.addToMyLists } return copyA; }); this.setState({ ds: newDatas, dataSource: this.state.dataSource.cloneWithRows(newDatas), }); } 複製data, 並依照勾選新增tag
componentDidUpdate() { let chooseCountNum = 0 let getALL = [
] this.state.ds.map(a => { if (a.addToMyLists === true) { getALL.push(a) return chooseCountNum += 1 } }) // 儲存&統計所有⾃自選品 this.saveToStorage(getALL) } saveToStorage = async (getMyBooks) => { try { await StorageHelper.setMySetting('code', JSON.stringify(getMyBooks)); } catch (err) { console.error(err); } }; 新增array放入被勾選到的書,並存起來來
state = { myBookCount: 0, myBookListName: [] } loadStorage =
async () => { this.setState({ myBookListName: [] }) let bookGet = await StorageHelper.getMySetting('code') let a = JSON.parse(bookGet) let newArray = [ ] a.forEach((thing) => { newArray.push(thing.volumeInfo.title) }) this.setState({ myBookCount: a.length, myBookListName: newArray }) }; <Text style={styles.instructions}>我收藏了了{this.state.myBookCount}本書</Text> { this.state.myBookListName.map((bookName, index) => { return (<Text key={index}>書名為:{bookName}</Text>) }) } componentDidMount() { this.props.navigation.addListener('didFocus', () => this.loadStorage()) } 讀取storage內的資料
Q&A 完整程式碼:https://github.com/Avonee/react-native_beginner_tutorial