【问题标题】:Reload React Native App from Function Call Within App从 App 内的函数调用重新加载 React Native App
【发布时间】:2018-03-29 23:42:31
【问题描述】:

我正在使用 AsyncStorage 将大学信息存储在 React Native 应用程序中。我正在为我的页面使用带有屏幕的堆栈和选项卡导航器。一旦有人选择了不同的大学,所有页面内容都会成功地以我想要的方式重新呈现。标题没有。我无法告诉它 AsyncStorage 变量已更新并更新状态并重新呈现自身。

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

编辑:这是我的设置页面中代码的 sn-p。当按下提交按钮时,我需要我的 AsyncStorage 变量的“名称”字段来更改我的索引文件的标题。

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>
);
  }
}

这是我的索引文件的主要部分。在设置中按下“提交”时,我需要更新的是 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>
);
  }
 }

【问题讨论】:

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


【解决方案1】:

使用AsyncStorage 确实是个坏主意,一旦你的代码变得更大,它就会产生问题,但你可以通过使用 setTimeout 到 AsyncStorage 来处理这个问题。

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

上面的例子我展示了如果你只想更新同一页面的值,你如何使用超时来异步存储。

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

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

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

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

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

import {
    DeviceEventEmitter
} from 'react-native';

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

【讨论】:

  • DeviceEventEmitter 上的文档似乎非常有限,但它似乎是一个快速的解决方案。因此,如果我在 ComponentDidMount 中有一个侦听器,比如我的索引文件(我的标题文本在其中确定),我将根据该侦听器的执行时间在哪里进行状态更改?并且 .emit 将在我的设置屏幕中被调用,其中 AsyncStorage 值被更新。当调用更新变量的函数时,我在设置中有一行: AsyncStorage.setItem('schoolObj', JSON.stringify(object));然后我需要将它发送回索引并即时更新标题。
  • 您的 asyncStorage 现在有一个更新的值,对吗?所以你需要在你需要的地方使用那个 asyncStorage 值。
【解决方案2】:

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

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

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

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

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

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

首先从Context(学习曲线较少)开始,如果您想走得更远,请尝试第二个Redux(学习曲线陡峭)

希望这会有所帮助。

【讨论】:

  • 您说得对,完全刷新将是矫枉过正且未优化的事实。如果有一行代码可以执行刷新,这似乎是最简单的解决方案。似乎 Redux 是被广泛接受的解决方案;我只需要花时间学习它。至于 Context,我没听说过,它看起来确实是一个有用的工具。将其与 AsyncStorage 变量的更改联系起来似乎有些困难,但这也可能是要走的路。感谢您的反馈;很有帮助。
猜你喜欢
  • 2019-05-03
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 2016-11-05
  • 2022-12-10
  • 2020-01-07
  • 2021-10-04
  • 2018-10-27
相关资源
最近更新 更多