这两个特性也是目前随着前端 UI 越来越复杂,用来解耦的好方法。
单向数据流 Unidirectional data flow
简单来说单向数据流就是确保数据是单向绑定的,例如下图,数据的更新永远是顺着一个方向而不能反过来。
要做到数据的单向流动,需要做到以下两个方面。
数据状态只保存在一处。 Single source of truth
数据状态只保存在一处不用多说了,主要就是数据结构的设计,要避免把一种状态用两种描述放在不同的表里,然后再来同步。这样你再精巧的代码都弥补不了数据结构的缺陷。数据结构比代码重要。
状态的读写操作分开,在状态改变后通知更新 UI。
写操作直接操作数据,不要有中间状态,然后通知数据更新。Realm 是通过 realm.write 来处理所有的写操作。
realm.write(() => {
let myCar = realm.create('Car', { //创建新的记录
make: 'Honda',
model: 'Civic',
miles: 1000,
});
myCar.miles += 20; // 更新
realm.delete(myCar); //删除
});
如果你在realm.write() 之外试图写操作,就会抛出错误。
在更新后,会有一个 change event
realm.addListener('change', () => {
//通知更新界面
})
这样读写分开可以降低程序的复杂度,使得逻辑更清晰。至于界面的更新就交给 React 了,配合得正好。
所以其实可以考虑直接使用 Realm 来作为 Flux 架构的 Store,而不用 Redux。(一个猜测
Reactive
Realm 查询的结果是自动更新的。例如
输入姓名后点击 Save,人数就自动更新。在上面例子中,我们只需在 componentWillMount 里查询(绑定)一次返回的 results 值, 此后只要 Person 数目改变,界面里的 results.length 就会改变,而不用再次去查询数据库了。React 会帮助你高效处理界面更新的部分。代码如下
class rmdemo extends Component {
constructor(props) {
super(props)
this.state = {
inputText: ''
}
}
componentWillMount(){
this.realm = new Realm({
schema:[{name:'Person', properties:{name: 'string'}}]
})
this.results = this.realm.objects('Person')
this.realm.addListener('change', () => {
this.forceUpdate()
})
}
_handleTouch(){
this.realm.write(()=>{
this.realm.create('Person', [this.state.inputText]);
})
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native and Realm!
</Text>
<Text style={styles.welcome}>
Count of Persons in Realm: {this.realm.objects('Person').length}
</Text>
<View style={{alignItems: 'center'}}>
<TextInput
style={{height: 40, width: 200, borderColor: 'gray', borderWidth: 1}}
onChangeText={(inputText) => this.setState({inputText})}
value={this.state.inputText}
/>
<TouchableWithoutFeedback onPress={this._handleTouch.bind(this)}>
<View>
<Text style={{fontSize: 24, color: 'blue'}}>
Save
</Text>
</View>
</TouchableWithoutFeedback>
</View>
</View>
)
}
}