我在TabBarIOS旁边有两个标签。
第一个标签是提供功能,用于将新项目添加到AsyncStorage
第二个标签显示AsyncStorage中的所有项目
但是当我运行我的应用程序时,在第一个选项卡中添加一个新项目后,导航到第二个选项卡,我看不到页面重新渲染,我将需要执行一个Command + R然后我看到我的新数据。< / p>
解决此问题的一种方法是在shouldComponentUpdate中读取asyncStorage,但请注意,反应会不断调用shouldComponentUpdate。虽然我只想强制按需更新UI。
因此,在本机反应中,更新另一个UI组件状态的正确方法是什么?
示例应用: https://drive.google.com/file/d/0B8kAIsj2xDnUMklIQmc0b3NiSVE/view?usp=sharing
答案 0 :(得分:3)
这就是我正在谈论的内容。一旦完成,你可能想稍微重构一下,但总的来说,我认为最终会看到这种情况。关于正确使用生命周期功能,我还有很多东西需要学习,而且我现在还不确定你是否需要它们。
我基本上删除了你的NavigatorIOS。我认为这是一个错误。相反,我用组件替换它们,将数据作为道具传递下去,包括按下按钮的回调函数。我已经将addData函数移动了一个级别。
class AppContainer extends Component {
constructor(props) {
super(props);
this.state = {
selectedTab: 'data-list',
dataLen: 0
}
AsyncStorage.getItem("all-data")
.then((data)=>{
if(!data)
{
data = "[]";
}
var dataObj = JSON.parse(data);
this.setState({
dataLen : dataObj.length
});
});
this.addData.bind(this);
}
addData() {
AsyncStorage.getItem("all-data")
.then((data)=>{
if(!data)
{
data = "[]";
}
var dataObj = JSON.parse(data);
dataObj.push({
val: Date.now()
});
AsyncStorage.setItem("all-data", JSON.stringify(dataObj));
this.setState({
dataLen: dataObj.length
});
});
}
render() {
return (
<TabBarIOS style={styles.container}>
<TabBarIOS.Item
title="Add Data"
selected={this.state.selectedTab == 'add-data'}
onPress={()=> this.setState({selectedTab: 'add-data'})}
>
<AddData onButtonPress={this.addData} dataLen={this.state.dataLen} />
</TabBarIOS.Item>
<TabBarIOS.Item
title="Data List"
selected={this.state.selectedTab == 'data-list'}
onPress={()=> this.setState({selectedTab: 'data-list'})}
badge={this.state.dataLen}
>
<DataList dataLen={this.state.dataLen} />
</TabBarIOS.Item>
</TabBarIOS>
);
}
}
这将显着简化您的子组件...
class AddData extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text>{this.props.dataLen}</Text>
<TouchableHighlight
onPress={this.props.onButtonPress}
style={styles.button}>
<Text style={styles.buttonText}>Plus One</Text>
</TouchableHighlight>
</View>
);
}
}
class PlayerList extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View style={styles.container}>
<Text>{this.props.dataLen}</Text>
</View>
);
}
}
答案 1 :(得分:2)
你有没有考虑过使用Redux或同等的东西? 我有同样的问题。最终使用Redux为我解决了它。
我强烈推荐您使用Redux的official documentation。
我不会尝试教你Redux,因为文档已经非常好了。但我会尝试概述一些部分,让您了解如何使用Redux。我真的无法更新您现有的应用程序,因为这不是一个微不足道的调整。如果大多数变化对你来说都很神秘,那就不够了。
在操作创建者中,您需要致电AsyncStorage
并使用 reducer 中的值来更新您的州。重要的部分是组件与Redux存储的连接。您必须将其与自NavigatorIOS doesn't update when passProps update以来通过NavigatorIOS
加载的组件相关联。
<NavigatorIOS
initialRoute={{
component: MyView,
title: 'My View Title',
}}
/>
// MyView Component
...
class MyView extends Component {
...
}
// Prepare the information of the global state and only pass the relevant values as `props` to the component.
function mapStateToProps(state) {
const { isFetching, isError, lastUpdated } = state.posts;
const { entities: posts } = state.posts || { entities: {} };
return {
posts,
isFetching,
isError,
lastUpdated
}
}
export default connect(mapStateToProps)(MyView);