React Native Fetch API请求返回旧数据 图片及跳转链接更新不生效
解决方案
核心问题根源
你的问题由两层缓存共同导致:
- 接口请求缓存:端侧/网络代理层会缓存JSON接口的返回结果,部分平台的fetch实现对
Cache-Control头的支持存在缺陷,导致你加的no-cache未生效 - 图片缓存:React Native内置的
Image组件默认会按图片URL做持久化缓存,只要URL不变,哪怕服务端替换了同地址的图片内容,端侧也会优先读取本地缓存
可直接落地的修改方案
1. 彻底解决JSON接口缓存问题
给接口URL添加动态时间戳后缀,保证每次请求的URL唯一,完全绕开所有缓存层,比单纯配置缓存头更可靠:
// 把原来的fetch地址改成带时间戳的形式 const response = await fetch(`https://teleantillas.com.do/wp-content/uploads/telestream/json/PublicidadTeleStream.json?t=${Date.now()}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', // 可以保留缓存头做双重保险,补充全字段 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache' } })
2. 解决图片缓存问题
同样给图片URL加动态后缀,如果不需要严格的实时性,也可以和服务端配合,在JSON里新增图片版本号字段,只有版本变更时才重新拉取图片,节省流量:
// 修改Image组件的source配置 <Image style={styles.imgad} source={{uri: `${item.URLHome}?t=${Date.now()}`}} />
3. 补充实时更新优化(可选)
你当前只在组件首次加载时拉取一次配置,用户如果长期挂着应用后台,切回前台时不会更新数据,可以添加AppState监听,应用从后台切回前台时主动拉取最新配置,无需用户重启应用。
修改后完整业务代码参考
import { AppState } from 'react-native' // 不需要监听可以去掉该行 export default class GetDatajson extends Component{ constructor(props) { super(props); this.state = { data: [], isLoading: true, appState: AppState.currentState // 不需要监听可以去掉该行 }; } async fetchData(){ try{ const response = await fetch(`https://teleantillas.com.do/wp-content/uploads/telestream/json/PublicidadTeleStream.json?t=${Date.now()}`, { method: 'GET', headers: { Accept: 'application/json', 'Content-Type': 'application/json', 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache' } }) const json = await response.json(); this.setState({ data: json.Home }); }catch(error) { console.error(error);} finally{ this.setState({ isLoading: false }); } } // 不需要监听AppState可以去掉以下三个生命周期方法 componentDidMount() { AppState.addEventListener('change', this.handleAppStateChange); this.fetchData(); } handleAppStateChange = (nextAppState) => { if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') { // 应用从后台切回前台,刷新配置 this.fetchData(); } this.setState({ appState: nextAppState }); } componentWillUnmount() { AppState.removeEventListener('change', this.handleAppStateChange); } // 不需要监听AppState可以去掉以上三个方法 render(){ const { data, isLoading } = this.state; return( <View style ={styles.jsonHome}> {isLoading ? <ActivityIndicator/> : ( <FlatList data={data} keyExtractor={({ id }, index) => id} renderItem={({ item }) => ( <TouchableOpacity style={styles.i8mgcontainer} onPress={()=> Linking.openURL(item.LinkHome) }> <Image style={styles.imgad} source={{uri: `${item.URLHome}?t=${Date.now()}`}} /> </TouchableOpacity> )} /> )} </View> ) } }
内容的提问来源于stack exchange,提问作者Raynier lara
相关产品推荐
相关产品推荐

