ReactNative Hooks

RN + MobX + react hook

2021-04-08  本文已影响0人  精神病患者link常

更加详细请查看官方文档
https://mobx.js.org/README.html
https://github.com/mobxjs/mobx-react
https://mobx-react.js.org/observer-hoc
https://github.com/mobxjs/mobx-react-lite

安装 MobX

npm install --save-dev @babel/plugin-proposal-decorators
npm install mobx-react --save
npm install mobx --save

当前版本
"mobx": "^6.1.8",
"mobx-react": "^7.1.0",
设置 babel.config.js
plugins: [
    'react-native-reanimated/plugin',
    ["@babel/plugin-proposal-decorators", { "legacy": true }],  <-----add
  ],

单个页面内部使用mobx

第一种方式 observer

⚠️推荐此种方式
方法组件使用observer包裹
observer<P>(baseComponent: FunctionComponent<P>): FunctionComponent<P>

import {observer, useLocalObservable, Observer, useObserver} from 'mobx-react'

export default Home = observer(({ route, navigation })=>{
  
  const homeStore = useLocalObservable(() => ({
    address: '北京',
    isFriend: false,
    toDoList: [],
    bannerList: [],
    changeFiend(isF) {
      this.isFriend = isF
    },
    get friendMsg(){
      return this.isFriend ? '好朋友' : '陌生人'
    }
  }))

  const onGoodFriend = React.useCallback(()=>{
    homeStore.changeFiend(true)
  })

  const onStranger = React.useCallback(()=>{
    homeStore.changeFiend(false)
  })
  
  return (
    <View style={styles.mainView}>
      <View style={{marginBottom:100}}>
        <Text>mobx数据测试:</Text>
        <Text>{homeStore.address}</Text>
        <Text>你们是:{homeStore.friendMsg}</Text>
        <View style={{flexDirection:'row',justifyContent:'center'}}>
          <TouchableOpacity style={styles.btn} onPress={onGoodFriend}>
            <Text>好朋友</Text>
          </TouchableOpacity>
          <TouchableOpacity style={styles.btn} onPress={onStranger}>
            <Text>陌生人</Text>
          </TouchableOpacity>
        </View>
      </View>
      <Text>Home</Text>
    </View>
  );
})

第二种方式 <Observer>

使用Observer包裹的会自动改变,而外部的不会

<Observer>{renderFn}</Observer>
import {observer, useLocalObservable, Observer, useObserver} from 'mobx-react'

export default Chat=({ route, navigation })=>{

  const chatStore = useLocalObservable(() => ({
    chatName: '张三',
    changeChatName(name) {
      this.chatName = name
    },
  }))

  const onChangeChatName = React.useCallback(()=>{
    chatStore.changeChatName('李四')
  })

  return (
    <View style={styles.mainView}>
      <Text>外部数据{chatStore.chatName}</Text>
      <Observer>
        {
          ()=>{
            return <View>
              <Text>内部数据:{chatStore.chatName}</Text>
              <TouchableOpacity style={{marginTop:15}} onPress={onChangeChatName}>
                <Text>点击修改</Text>
              </TouchableOpacity>
            </View>
          }
        }
      </Observer>
      <Text>Chat</Text>
    </View>
  );
};

第三种方式 useObserver

return 的组件使用 useObserver包裹
⚠️⚠️⚠️⚠️[mobx-react-lite] 'useObserver(fn)' is deprecated. Use<Observer>{fn}</Observer>instead, or wrap the entire component inobserver.


import {observer, useLocalObservable, Observer, useObserver} from 'mobx-react'

export default Contact=({ route, navigation })=>{

  const contactStore = useLocalObservable(() => ({
    chatName: '张三',
    changeChatName(name) {
      this.chatName = name
    },
  }))

  const onChangeChatName = React.useCallback(()=>{
    contactStore.changeChatName('李四')
  })

  return useObserver(()=>{
    return <View style={styles.mainView}>
      <Text>{contactStore.chatName}</Text>
      <TouchableOpacity style={{marginTop:15}} onPress={onChangeChatName}>
        <Text>点击修改</Text>
      </TouchableOpacity>
    <Text>Contact</Text>
  </View>
  })
};

全局使用mobx (没有找到解决数据持久化的办法,即类似redux-persist)
提前了解:http://react.caibaojian.com.cn/docs/context.html
⚠️:可以打开app就调用用户信息接口,然后更新userInfo

程序入口APP.js

import { observable } from 'mobx';

const userInfo = observable({
  name: "胡桃",
  jobTitle:'往生堂堂主',
  changeName(name){
    this.name = name
  },
  changeJobTitle(title){
    this.jobTitle = title
  },
})

const globalInfo = observable({
  udid: "1234567890",
  changeUDID(udid){
    this.udid = udid
  },
})

export default App=()=>{
  console.log('App');
    return (
      <Provider userInfo={userInfo} globalInfo={globalInfo}>
        <NavigationContainer>
          <DrawerNavigator/>
        </NavigationContainer>
      </Provider>
  );
};

其他页面使用前的准备
需要先获取Provider传递的数据

import { MobXProviderContext} from 'mobx-react'
// 这里return的就是 {userInfo, globalInfo}
export const useStores=()=> {
  return React.useContext(MobXProviderContext)
}

然后其他页面就可以通过 调用useStores来获取相应的数据
⚠️ 使用observer包裹才会实时刷新,设置同样的数据不会刷新

import {observer } from 'mobx-react'
import {action} from 'mobx'

export default Mine=observer(({ route, navigation })=>{
 console.log('Mine');
 const {userInfo,globalInfo} = useStores()

 const onChangeUserInfo=React.useCallback(()=>{
   userInfo.changeName('琴')
   userInfo.changeJobTitle('西风骑士团代理团长')
 })
 const onChangeUserName=React.useCallback(action(()=>{
   userInfo.sex = '女' // 增加新的字段
 }))

 const onChangeUDID=React.useCallback(()=>{
   globalInfo.changeUDID('qwer')
 })


 return (
   <View style={styles.mainView}>
     <View style={{marginBottom:200}}>
       <Text>用户信息</Text>
       <Text>姓名:{userInfo.name}{userInfo.sex}</Text>
       <Text>职位:{userInfo.jobTitle}</Text>
       <Text>UDID:{globalInfo.udid}</Text>
       <TouchableOpacity style={styles.btn} onPress={onChangeUserInfo}>
         <Text>修改用户</Text>
       </TouchableOpacity>
       <TouchableOpacity style={styles.btn} onPress={onChangeUserName}>
         <Text>修改用户-增加新的属性</Text>
       </TouchableOpacity>
       <TouchableOpacity style={styles.btn} onPress={onChangeUDID}>
         <Text>修改UIDI</Text>
       </TouchableOpacity>
     </View>
     <Text>Mine</Text>
   </View>
 );
})

网络请求Promise返回数据修改

const HttpFetch = ()=>{
  return new Promise((resolve,reject)=>{
    setTimeout(() => {
      resolve('从网络返回的数据')
    }, 3000);
  })
}

const homeStore = useLocalObservable(() => ({
    httpResult:'',
    getFetchResult(){
      HttpFetch().then(action((result)=>{
        this.httpResult = result
      }))
    }
  }))
上一篇下一篇

猜你喜欢

热点阅读