从App中的函数调用重新加载React Native App

时间:2018-03-29 23:42:31

标签: reactjs react-native react-navigation asyncstorage react-props

我正在使用AsyncStorage在React Native应用程序中存储大学信息。我正在为我的页面使用Stack和Tab Navigators with Screens。一旦有人选择了不同的大学,所有页面内容都会成功重新呈现我想要的方式。标题没有。我无法告诉它AsyncStorage变量已更新并更新状态并重新呈现自身。

我想在有人选择新大学时简单刷新整个应用程序。然后变量,状态和道具都将是最新的,即与启动开发菜单和重新加载应用程序相同。我想在应用程序中使用一个调用函数的按钮并在内部执行此操作。

编辑:以下是我的“设置”页面中的代码片段。当按下提交按钮时,我需要在我的索引文件的标题中更改AsyncStorage变量的“name”字段。

saveMSU() {
const object = {
  name: 'MONTANA STATE UNIVERSITY',
  site: 'http://msubobcats.com/index.aspx',
};
AsyncStorage.setItem('schoolObj', JSON.stringify(object));
  }
  saveUM() {
const object = {
  name: 'UNIVERSITY OF MONTANA',
  site: 'http://gogriz.com/',
};
AsyncStorage.setItem('schoolObj', JSON.stringify(object));
  }
  updateSchool = async () => {
this.props.navigation.dispatch(NavigationActions.reset({
  index: 0,
  key: null,
  actions: [NavigationActions.navigate({ routeName: 'Tabs' })]
}));
  }
 render() {
return (
  <View style={styles.container}>
    <Text>CHOOSE YOUR UNIVERSITY</Text>
    <TouchableOpacity onPress={this.saveMSU}>
      <Text>Montana State University</Text>
    </TouchableOpacity>
    <TouchableOpacity onPress={this.saveUM}>
      <Text>University of Montana</Text>
    </TouchableOpacity>
    <Button onPress={this.updateSchool}>
      SUBMIT
    </Button>
  </View>
);
  }
}

这是我的索引文件的主要部分。在Setting中按下“Submit”时我需要更新的是this.state.school.site和this.state.school.name。我喜欢使用deviceEventEmitter的想法,但我对如何实际实现它感到有点困惑。

class App extends Component {
  state = { school: Object, loaded: false };
  componentWillMount() {
this.retrieveItem('schoolObj').then((current) => {
  this.setState({ school: current, loaded: true });
}).catch((error) => {
  console.log('Unable to retrieve data: ' + error);
});
  }
  async retrieveItem(key) {
try {
  const schoolItem = await AsyncStorage.getItem(key);
  const item = JSON.parse(schoolItem);
  return item;
} catch (error) {
  console.log(error.message);
}
return;
  }
  render() {
return (
  <View style={{ flex: 1 }}>
    <Image style={styles.logoStyle} source={require('./media/UAT.png')} />
    { this.state.loaded &&
      <TouchableOpacity onPress={() => Linking.openURL(this.state.school.site)}>
        <Text style={styles.headingStyle}>
            {Object.values(this.state.school.name)}
        </Text>
      </TouchableOpacity>
    }
    <Root screenProps={this.state.school} />
  </View>
);
  }
 }

2 个答案:

答案 0 :(得分:0)

有点不清楚为什么要重新加载整个应用程序只是为了从不同的屏幕访问适当的数据。发布您的代码的简化版本可能很有用,这样您的意图就会明确一些。

我假设这是因为您没有状态容器来管理您的应用程序状态?

所以,这里有几件事要尝试

Redux将管理应用程序状态。因此,您可以从任何屏幕基本上“setState”并从任何屏幕访问该状态(简化,但基本上就是它的作用)

与Redux基本相同,但没有很多样板。在进入Redux之前,这将是一个很好的起点。请查看Using React Context API video了解如何使用它

最后,一旦有人选择了新的大学,你不应该(不应该)“刷新整个应用程序”。这将是一种过度杀伤和高度未经优化(更不用说不必要)的做事方式。此外,随着您的应用程序变得更大(非平凡),这种方法根本无法扩展。

首先从Context(较少的学习曲线)开始,如果你想更进一步,请尝试Redux(陡峭的学习曲线)第二

希望这会有所帮助。

答案 1 :(得分:0)

一旦你的代码越来越大,使用AsyncStorage创建问题真是个坏主意,但你可以通过使用setTimeout来处理这个问题。

AsyncStorage.setItem('title', JSON.stringify(responseJson.data.title));
                                _this.setState({getTitle: true});
                            }, 3000)

上面的例子我展示了如果你只想在同一页面更新值,你如何使用超时到asyncStore。

如果要将AsyncStorage vale更新为其他组件(页面),可以使用广播方法:

DeviceEventEmitter.emit('changeTitle', responseJson, null);

将上面一行代码放在要更新AsyncStorage的位置。现在要在其他页面上获取它,或者在项目中的任何地方放置,只需将下面的代码放在componentDidMount中:

componentDidMount() {
        this.emitter = DeviceEventEmitter.addListener('changeToolBarTitle', this.changeToolBarTitle, null);
    }

不要忘记在这两个文件中导入DeviceEventEmitter

import {
    DeviceEventEmitter
} from 'react-native';

我希望你能得到解决方案。