美文网首页React Nativemobxmobx
ReactNative Mobx,Redux作者推荐,比Redu

ReactNative Mobx,Redux作者推荐,比Redu

作者: Freedom_J | 来源:发表于2016-12-27 16:03 被阅读470次
    运行截图

    最近在学习React的架构,看了很火的Redux,然而学习Redux的过程异常痛苦。
    于是乎发现了Redux作者推荐的另一种状态管理库,Mobx

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

    用Mobx做状态管理真的是爽爆了,简单易懂,大大提升编码效率,替代redux的首选,废话不多说,进入正题。

    1.初始化项目

    首先创建一个新的React Native项目,打开终端输入

    react-native init ReactNativeMobx
    

    项目创建成功后,安装mobx和mobx-react

    cd ReactNativeMobx
    
    npm i mobx mobx-react --save
    

    接下来在根目录下创建名为app的文件夹,在app文件夹下创建名为mobx的文件夹,在mobx文件夹下创建listStore.js,在app文件夹下创建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.创建ObservableListStore类
    3.@observable list[],监听list的变化
    4.三个方法,添加列表,删除列表,添加一条数据
    5.导出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)
    

    以上重点为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
    

    以上,所有代码直接复制粘贴就OK

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

    相关文章

      网友评论

        本文标题:ReactNative Mobx,Redux作者推荐,比Redu

        本文链接:https://www.haomeiwen.com/subject/vaxevttx.html