我遇到了一个问题,我在多个组件中基于 AsyncStorage 中的相同键设置状态。由于 state 是在 componentDidMount 中设置的,并且这些组件不一定会在导航上卸载和挂载,因此 state 值和 AsyncStorage 值可能会不同步。
这是我能做的最简单的例子。
组分 A
A 只是设置导航和应用程序。
var React = require('react-native');
var B = require('./B');
var {
AppRegistry,
Navigator
} = React;
var A = React.createClass({
render() {
return (
<Navigator
initialRoute={{
component: B
}}
renderScene={(route, navigator) => {
return <route.component navigator={navigator} />;
}} />
);
}
});
AppRegistry.registerComponent('A', () => A);
B组份
B 在挂载时从 AsyncStorage 读取,然后设置为状态。
var React = require('react-native');
var C = require('./C');
var {
AsyncStorage,
View,
Text,
TouchableHighlight
} = React;
var B = React.createClass({
componentDidMount() {
AsyncStorage.getItem('some-identifier').then(value => {
this.setState({
isPresent: value !== null
});
});
},
getInitialState() {
return {
isPresent: false
};
},
goToC() {
this.props.navigator.push({
component: C
});
},
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>
{this.state.isPresent
? 'Value is present'
: 'Value is not present'}
</Text>
<TouchableHighlight onPress={this.goToC}>
<Text>Click to go to C</Text>
</TouchableHighlight>
</View>
);
}
});
module.exports = B;
组分 C
C 从 AsyncStorage 中读取与 B 相同的值,但允许您更改该值。更改会切换状态和 AsyncStorage 中的值。
var React = require('react-native');
var {
AsyncStorage,
View,
Text,
TouchableHighlight
} = React;
var C = React.createClass({
componentDidMount() {
AsyncStorage.getItem('some-identifier').then(value => {
this.setState({
isPresent: value !== null
});
});
},
getInitialState() {
return {
isPresent: false
};
},
toggle() {
if (this.state.isPresent) {
AsyncStorage.removeItem('some-identifier').then(() => {
this.setState({
isPresent: false
});
})
} else {
AsyncStorage.setItem('some-identifier', 'some-value').then(() => {
this.setState({
isPresent: true
});
});
}
},
goToB() {
this.props.navigator.pop();
},
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>
{this.state.isPresent
? 'Value is present'
: 'Value is not present'}
</Text>
<TouchableHighlight onPress={this.toggle}>
<Text>Click to toggle</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.goToB}>
<Text>Click to go back</Text>
</TouchableHighlight>
</View>
);
}
});
module.exports = C;
如果在 C 中切换然后返回到 B,则 B 中的状态和 AsyncStorage 中的值现在不同步。据我所知, navigator.pop() 不会触发我可以用来告诉 B 刷新值的任何组件生命周期函数。
我知道但并不理想的一种解决方案是让 B 的状态成为 C 的道具,并给 C 一个回调道具来切换它。如果 B 和 C 始终是直接的父子关系,那将很有效,但在真正的应用程序中,导航层次结构可能会更深。
无论如何在导航事件之后触发组件上的功能,还是我缺少的其他东西?