MobX 是一款十分优秀的状态管理库,不但书写简洁还非常高效。当然这是我在使用之后才体会到的,当初试水上车的主要原因是响应式,考虑到可能会更符合 vue 过来的思考方式。然而其实两者除了响应式以外并没有什么相似之处。
在使用过程中走了不少弯路,一部分是因为当时扫两眼文档就动手,对 MobX 机制理解得不够;其它原因是 MobX 终究只是一个库,会受限于 react 机制,以及与其它非 MobX 管理组件的兼容问题。当中很多情况在文档已经给出了说明,我根据自己遇到的再做一番总结。
与非响应式的组件一起工作时,MobX 有时需要为它们提供一份非响应式的数据副本,以免 observable 被其它组件修改。
使用 React Navigation 导航时,如果要交由 MobX 管理,则需要手动配置导航状态栈,此时用 @observable.ref “浅观察”可避免状态被 React Navigation 修改时触发 MobX 警告。
当 Navigator 接受 navigation props 时代表导航状态为手动管理。
import { addNavigationHelpers, StackNavigator } from 'react-navigation'
import { observable, action } from 'mobx'
import { Provider, observer } from 'mobx-react'
import AppComp from './AppComp'
const AppNavigator = StackNavigator({
App: { screen: AppComp },
// ...
}, {
initialRouteName: 'App',
headerMode: 'none'
})
@observer
export default class AppNavigation extends Component {
@observable.ref navigationState = {
index: 0,
routes: [
{ key: 'App', routeName: 'App' }
],
}
@action.bound dispatchNavigation = (action, stackNavState = true) => {
const previousNavState = stackNavState ? this.navigationState : null
this.navigationState = this.AppNavigator.router.getStateForAction(action, previousNavState)
return this.navigationState
}
render () {
return (
<Provider
dispatchNavigation={this.dispatchNavigation}
navigationState={this.navigationState}
>
<AppNavigator navigation={addNavigationHelpers({
dispatch: this.dispatchNavigation,
state: this.navigationState,
})} />
</Provider>
)
}
}
MobX 还提供其它方便的数据结构来存放非响应式数据。
比如使用 SectionList 的时候,我们要为其提供数据用于生成列表,由于 Native 官方的实现跟 MobX 不兼容,这个数据不能是响应式的,不然 MobX 会报一堆警告。
MobX 有个 mobx.tojs() 方法可以导出非响应式副本;如果结构不相同还可以使用 @computed 自动生成符合的数据。但这两个方法每次添加项目都要全部遍历一遍,可能会存在性能问题。
这时其实可以维护一个 observable.shallowArray,里面只放 key 数据,只用于生成列表(像骨架一样)。传给 SectionList 的 sections props 时 slice数组复制副本(shallowArray 里的数据非响应式,所以只需浅复制,复杂度远小于上面两种方式)。
然后 store 维护一个 observable.map 来存放每个项的数据,在项(item)组件中 inject store 进去,再利用 key 从 map 中获取数据来填充。
通过 shallowArray 可以让 MobX 识别列表长度变化自动更新列表,利用 map 维护项数据可以使每个项保持响应式却互不影响,对长列表优化效果很明显。
// store comp
class MyStore {
@observable sections = observable.shallowArray()
@observable itemData = observable.map()
@action.bound appendSection (section) {
const data = []
section.items.forEach(action(item => {
this.itemData.set(item.id, item)
data.push({key: item.id})
}))
this.sections.push({
key: section.id,
data
})
}
}
// MyList comp
import { SectionList } from 'react-native'
@inject('myStore')
@observer
class MyList extends React.Component {
_renderItem = ({item}) => <SectionItem id={item.key} />
render () {
return (
<SectionList
getItemLayout={this._getItemLayout}
sections={this.props.myStore.sections.slice()}
renderSectionHeader={this._renderSectionHeader}
renderItem={this._renderItem}
/>
)
}
}
// SectionItem comp
@inject('myStore')
@observer
class SectionItem extends React.Component {
render () {
const {myStore, id} = this.props
const itemData = myStore.itemData.get(id)
return (
<Text>{itemData.title}</Text>
)
}
}
利用 @computed 缓存数据可以做一些优化。
比如有一个响应式的数组 arr,一个组件要根据 arr 是否为空更新。如果直接访问 arr.length,那么只要数组长度发生变化,这个组件都要 render 一遍。
此时利用 computed 生成,组件只需要判断 isArrEmpty 就可以减少不必要的更新:
@computed get isArrEmpty () {
return this.arr.length <= 0
}
因 js 机制 MobX 不能检测属性的增删,所以最好用 observable.map 取代简单 {} 对象。另外 MobX 没有提供 Set 支持,可以用 key 和 value 一样的 Map 代替。
这条规则在文档也提到,原因很简单,MobX 对于一个 observer 组件,是通过访问属性来记录依赖的。所以哪怕父组件里没有用到这个属性,只是为了作为 props 传给子组件,MobX 还是算它依赖了这个属性,于是会产生不必要的更新。最好的方式是将数据统一放在 store 中,子组件通过 inject store 方式获取数据。
由于 React 的机制,MobX 只能在组件层面发光发热,对于组件内部就无能为力了。所以大组件用 MobX 很容易卡死(用其它也会),小组件才能真正发挥 MobX 自动管理更新的优势。
在移动应用程序开发领域,跨平台应用程序框架就是舞台的主角。企业使用这些框架来开发 Web 和移动应用程序。当你要为你的企业开发 Web 或移动应用程序时,你需要坚持以客户为中心的原则来寻求解决方案
感觉到React Native的写APP效率真的很高,在NPM上搜索了一些插件,发现React Native的生态圈现在真的很大。绝对可以满足现在很多APP的需求,而不止企业类的APP了。
我们身处科技高速发展的时代;互联网日新月异,移动应用程序开发产业也在大踏步前进。多年来,移动应用的市场需求呈爆发式增长;众多企业都在开发自己的移动应用程序,或者用于促销自己的产品,或者用来向客户提供更好的服务
React-Native创建组件的三种方式:ES6创建组件的方式、ES5创建组件的方式、函数式。当创建的方式不同的时候,其实他们的导入方式也有几种。
继微信正式推出微信小程序后,各个大厂陆续发布了各自的小程序平台 —— 支付宝小程序、百度小程序、头条小程序,跨小程序平台开发也成为了众多小程序开发者要面临的问题。
目前主流的移动端平台主要是Android和iOS,为了尽可能复用代码和节省开发成本,各大巨头都开发了自己的跨平台框架,比如Facebook的React-Native、阿里的Weex、Cordova,以及今年Google开发者大会上介绍的Flutter框架
如何看待百度要求内部全面停止使用 React / React Native?非常的火爆,以至于引发了前端的一片热议,整个圈子都在讨论这件事。
Fluter是由google一款移动UI框架,意在帮助开发者在 iOS 和 Android 两个平台开发高质量的原生应用,Flutter是免费和开源的,就像Android SDK一样,并且可以与现有代码一起使用。Flutter的主要吸引力在于iOS和Android的智能和快速移动开发。
React Native 的出现,让前端工程师拥有了使用 JavaScript 编写原生 APP 的能力。相比之前的 Web app 来说,对于性能和用户体验提升了非常多。但是 React Native 的代码只兼容两个平台(iOS 和 Android),并没有兼容 Web 端访问。于是 React web 就出现了
选择react-native的几个重要因素:跨平台、基于React框架开发,组建化,响应式思路,调试方式可以缩短开发周期(在开发者熟练使用的情况下),也可以调整前端开发资源、热更新、新技术调研,扩展技术栈
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!