ReactNative Mobx,Redux作者推薦窗骑,比Redux簡單太多

運(yùn)行截圖

最近在學(xué)習(xí)React的架構(gòu)女责,看了很火的Redux,然而學(xué)習(xí)Redux的過程異常痛苦创译。
于是乎發(fā)現(xiàn)了Redux作者推薦的另一種狀態(tài)管理庫抵知,Mobx

unhappy with redux? try mobx   //Redux作者的原話

用Mobx做狀態(tài)管理真的是爽爆了,簡單易懂,大大提升編碼效率刷喜,替代redux的首選,廢話不多說残制,進(jìn)入正題。

1.初始化項(xiàng)目

首先創(chuàng)建一個新的React Native項(xiàng)目吱肌,打開終端輸入

react-native init ReactNativeMobx

項(xiàng)目創(chuàng)建成功后,安裝mobx和mobx-react

cd ReactNativeMobx
npm i mobx mobx-react --save

接下來在根目錄下創(chuàng)建名為app的文件夾仰禽,在app文件夾下創(chuàng)建名為mobx的文件夾氮墨,在mobx文件夾下創(chuàng)建listStore.js,在app文件夾下創(chuàng)建App.js(程序首頁)和NewItem.js(程序二級界面)如下圖

Snip20161227_3.png

2.代碼部分

listStore.js的代碼:

import {observable} from 'mobx'

let index = 0

class ObservableListStore {
  @observable list = []
  addListItem (item) {
    this.list.push({
      name: item, 
      items: [],
      index
    })
    index++
  }

  removeListItem (item) {
    console.log('item:::', item)
    this.list = this.list.filter((l) => {
      return l.index !== item.index
    })
  }

  addItem(item, name) {
    this.list.forEach((l) => {
      if (l.index === item.index) {
        l.items.push(name)
      }    
    })
  }
}

const observableListStore = new ObservableListStore()
export default observableListStore

上面代碼中
1.引用observable
2.創(chuàng)建ObservableListStore類
3.@observable list[]吐葵,監(jiān)聽list的變化
4.三個方法规揪,添加列表,刪除列表温峭,添加一條數(shù)據(jù)
5.導(dǎo)出ObservableListStore

接下來寫入口index代碼,憑你的喜好打開index.android.js或者index.ios.js猛铅,

import React, { Component } from 'react'
import App from './app/App'
import ListStore from './app/mobx/listStore'

import {
  AppRegistry,
  Navigator
} from 'react-native'

class ReactNativeMobX extends Component {
  renderScene (route, navigator) {
    return <route.component {...route.passProps} navigator={navigator} />
  }
  configureScene (route, routeStack) {
    if (route.type === 'Modal') {
      return Navigator.SceneConfigs.FloatFromBottom
    }
    return Navigator.SceneConfigs.PushFromRight
  }
  render () {
    return (
      <Navigator
        configureScene={this.configureScene.bind(this)}
        renderScene={this.renderScene.bind(this)}
        initialRoute={{
          component: App,
          passProps: {
            store: ListStore
          }
        }} />
    )
  }
}

AppRegistry.registerComponent('ReactNativeMobx', () => ReactNativeMobX)

以上重點(diǎn)為Navigator通過passProps將ListStore傳入,其余代碼為Navigator的初始化凤藏。

接下來寫我們程序首頁App.js的代碼

import React, { Component } from 'react'
import { View, Text, TextInput, TouchableHighlight, StyleSheet } from 'react-native'
import {observer} from 'mobx-react/native'
import NewItem from './NewItem'

@observer
class TodoList extends Component {
  constructor () {
    super()
    this.state = {
      text: '',
      showInput: false
    }
  }
  toggleInput () {
    this.setState({ showInput: !this.state.showInput })
  }
  addListItem () {
    this.props.store.addListItem(this.state.text)
    this.setState({
      text: '',
      showInput: !this.state.showInput
    })
  }
  removeListItem (item) {
    this.props.store.removeListItem(item)
  }
  updateText (text) {
    this.setState({text})
  }
  addItemToList (item) {
    this.props.navigator.push({
      component: NewItem,
      type: 'Modal',
      passProps: {
        item,
        store: this.props.store
      }
    })
  }
  render() {
    const { showInput } = this.state
    const { list } = this.props.store
    return (
      <View style={{flex:1}}>
        <View style={styles.heading}>
          <Text style={styles.headingText}>My List App</Text>
        </View>
        {!list.length ? <NoList /> : null}
        <View style={{flex:1}}>
          {list.map((l, i) => {
            return <View key={i} style={styles.itemContainer}>
              <Text
                style={styles.item}
                onPress={this.addItemToList.bind(this, l)}>{l.name.toUpperCase()}</Text>
              <Text
                style={styles.deleteItem}
                onPress={this.removeListItem.bind(this, l)}>Remove</Text>
            </View>
          })}
        </View>
         {!showInput &&  <TouchableHighlight
            underlayColor='transparent'      
            onPress={
                  this.state.text === '' ? this.toggleInput.bind(this)
                  : this.addListItem.bind(this, this.state.text)
                 }      
            style={styles.button}
             >
            <Text style={styles.buttonText}>
                {this.state.text === '' && '+ New List'}
                {this.state.text !== '' && '+ Add New List Item'}
            </Text>  
          </TouchableHighlight>}

          {showInput && <View style={{flexDirection: 'row'}}>
             <TextInput        
                style={styles.input}        
                onChangeText={(text) => this.updateText(text)} />    
             <TouchableHighlight
                style={styles.sureBtn}        
                onPress={
                  this.state.text === '' ? this.toggleInput.bind(this)
                  : this.addListItem.bind(this, this.state.text)
                } >      
             <Text>確定</Text>    
             </TouchableHighlight>  
      </View>}
    </View>
    );
  }
}

const NoList = () => (
  <View style={styles.noList}>
    <Text style={styles.noListText}>No List, Add List To Get Started</Text>
  </View>
)

const styles = StyleSheet.create({
  itemContainer: {
    borderBottomWidth: 1,
    borderBottomColor: '#ededed',
    flexDirection: 'row',
    justifyContent:'space-between'
  },
  item: {
    color: '#156e9a',
    fontSize: 18,
    flex: 1,
    padding: 20
  },
  deleteItem: {
    padding: 20,
    color: 'rgba(240,1,7,1.0)',
    fontWeight: 'bold',
    marginTop: 3
  },
  button: {
    height: 70,
    justifyContent: 'center',
    alignItems: 'center',
    borderTopWidth: 1,
    borderTopColor: '#156e9a'
  },
  buttonText: {
    color: '#156e9a',
    fontWeight: 'bold'
  },
  heading: {
    height: 80,
    justifyContent: 'center',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderBottomColor: '#156e9a'
  },
  headingText: {
    color: '#156e9a',
    fontWeight: 'bold'
  },
  input: {
    flex:1,
    height: 70,
    backgroundColor: '#f2f2f2',
    padding: 20,
    color: '#156e9a'
  },
  noList: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  noListText: {
    fontSize: 22,
    color: '#156e9a'
  },
    sureBtn: {
      width: 70,
      height: 70,
      justifyContent: 'center',
      alignItems: 'center',
      borderTopWidth: 1,
      borderColor: '#ededed'
  },
})

export default TodoList

二級界面NewItem.js代碼

import React, { Component } from 'react'
import { View, Text, StyleSheet, TextInput, TouchableHighlight } from 'react-native'

class NewItem extends Component {
  constructor (props) {
    super(props)
    this.state = {
      newItem: ''
    }
  }
  addItem () {
    if (this.state.newItem === '') return
    this.props.store.addItem(this.props.item, this.state.newItem)
    this.setState({
      newItem: ''
    })
  }
  updateNewItem (text) {
    this.setState({
      newItem: text
    })
  }
  render () {
    const { item } = this.props
    return (
      <View style={{flex: 1}}>
        <View style={styles.heading}>
          <Text style={styles.headingText}>{item.name}</Text>
          <Text
            onPress={this.props.navigator.pop}
            style={styles.closeButton}>×</Text>
        </View>
        {!item.items.length && <NoItems />}
        {item.items.length ? <Items items={item.items} /> : <View />}
        <View style={{flexDirection: 'row'}}>
          <TextInput
            value={this.state.newItem}
            onChangeText={(text) => this.updateNewItem(text)}
            style={styles.input} />
          <TouchableHighlight
            onPress={this.addItem.bind(this)}
            style={styles.button}>
            <Text>Add</Text>
          </TouchableHighlight>
        </View>
      </View>
    )
  }
}

const NoItems = () => (
  <View style={styles.noItem}>
    <Text style={styles.noItemText}>No Items, Add Items To Get Started</Text>
  </View>
)
const Items = ({items}) => (
  <View style={{flex: 1, paddingTop: 10}}>
   {items.map((item, i) => {
        return <Text style={styles.item} key={i}>? {item}</Text>
      })
    }
  </View>
)

const styles = StyleSheet.create({
  heading: {
    height: 80,
    justifyContent: 'center',
    alignItems: 'center',
    borderBottomWidth: 1,
    borderBottomColor: '#156e9a'
  },
  headingText: {
    color: '#156e9a',
    fontWeight: 'bold'
  },
  input: {
    height: 70,
    backgroundColor: '#ededed',
    padding: 20,
    flex: 1
  },
  button: {
    width: 70,
    height: 70,
    justifyContent: 'center',
    alignItems: 'center',
    borderTopWidth: 1,
    borderColor: '#ededed'
  },
  closeButton: {
    position: 'absolute',
    right: 17,
    top: 18,
    fontSize: 36
  },
  noItem: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  noItemText: {
    fontSize: 22,
    color: '#156e9a'
  },
  item: {
    color: '#156e9a',
    padding: 10,
    fontSize: 20,
    paddingLeft: 20
  }
})

export default NewItem

以上奸忽,所有代碼直接復(fù)制粘貼就OK

參考文章:https://medium.com/react-native-training/react-native-with-mobx-getting-started-ba7e18d8ff44#.jcqmbcd82

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市揖庄,隨后出現(xiàn)的幾起案子栗菜,更是在濱河造成了極大的恐慌,老刑警劉巖蹄梢,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疙筹,死亡現(xiàn)場離奇詭異,居然都是意外死亡禁炒,警方通過查閱死者的電腦和手機(jī)而咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幕袱,“玉大人暴备,你說我怎么就攤上這事∶峭悖” “怎么了馍驯?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玛痊。 經(jīng)常有香客問我汰瘫,道長,這世上最難降的妖魔是什么擂煞? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任混弥,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝗拿。我一直安慰自己晾捏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布哀托。 她就那樣靜靜地躺著惦辛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪仓手。 梳的紋絲不亂的頭發(fā)上胖齐,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天,我揣著相機(jī)與錄音嗽冒,去河邊找鬼呀伙。 笑死,一個胖子當(dāng)著我的面吹牛添坊,可吹牛的內(nèi)容都是我干的剿另。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼贬蛙,長吁一口氣:“原來是場噩夢啊……” “哼雨女!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起阳准,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤戚篙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后溺职,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岔擂,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年浪耘,在試婚紗的時候發(fā)現(xiàn)自己被綠了乱灵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡七冲,死狀恐怖痛倚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澜躺,我是刑警寧澤蝉稳,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掘鄙,受9級特大地震影響耘戚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜操漠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一收津、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦撞秋、人聲如沸长捧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽串结。三九已至,卻和暖如春舅列,著一層夾襖步出監(jiān)牢的瞬間肌割,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工剧蹂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留声功,地道東北人烦却。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓宠叼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親其爵。 傳聞我的和親對象是個殘疾皇子冒冬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評論 2 355

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