React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失

Posted

技术标签:

【中文标题】React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失【英文标题】:React Native - data is lost when switching between screens using react-navigation and react-redux 【发布时间】:2019-08-22 03:46:52 【问题描述】:

我将 react-redux 和 react-navigation 与我的 react native 应用程序一起使用。

我有一个名为photolist 的组件,它可以从数据库中获取所有照片。有两个屏幕调用这个组件。 userProfile 屏幕将 true 和 userId 传递给 photolist 以获取用户的照片;对于所有照片,feed 屏幕将 false 和 null 传递给 photolist

在 App.js 中,我将 Feed 屏幕和用户屏幕放在同一个堆栈中,以便轻松导航。

通过这种方法,我可以在 App 加载时加载主页,查看所有照片,然后转到用户页面并查看用户的照片。 但是从用户的页面,当我点击返回按钮回到主页面时,不再加载任何照片。 请注意,在这一系列动作中,photolist 组件的componentDidMount() 函数恰好被调用两次;从 userProfile 返回主提要时,不会再次调用它。

关于为什么会发生这种情况以及我该如何解决这个问题的任何想法?有没有办法保持导航结构,从userProfile 中单击后退按钮将带您回到您在主提要页面中的位置,而无需再次重新加载主提要?

photolist.js:

class PhotoList extends React.Component 
    constructor(props) 
        super(props);
    

    componentDidMount = () => 
        const  isUser, userId  = this.props;

        // load a single user's photos or all photos
        if (isUser) 
            this.props.loadFeed(userId);
         else     
            this.props.loadFeed();
        
    

    render()
        return (
            <View style=flex:1>
                <FlatList
                    data = (this.props.isUser) ? this.props.userFeed : this.props.mainFeed
                    keyExtractor = (item, index) => index.toString()

                    ...
                />
            </View>
        )
    


const mapStateToProps = state => 
    return 
        mainFeed: state.feed.mainFeed,
        userFeed: state.feed.userFeed
    


const mapDispatchToProps = 
    loadFeed
;

export default connect(mapStateToProps, mapDispatchToProps)(PhotoList);

feed.js:

<PhotoList isUser=false navigation=this.props.navigation/>

userProfile.js:

<PhotoList isUser=true userId=this.state.userId navigation=this.props.navigation/>

App.js:

const FeedScreenStack = createStackNavigator(
  FeedStack:  screen: feed ,
  UserProfile:  screen: userProfile 
);

【问题讨论】:

您能分享您的 API 操作 loadFeed() 吗?你能在返回时显示状态日志吗?至于返回尝试使用 shouldComponentUpdate() 生命周期方法来防止重新渲染。 @Javan_Poirier 我什至如何使用shouldComponentUpdate 生命周期方法来检查是否应该调用loadFeed()?如果我在同一个屏幕上,我知道它会如何工作,但我在这里的屏幕之间导航。我不能只检查 shouldComponentUpdate(nextProps, _) if (nextProps.navigation.state.routeName === "UserProfile") return false return true 之类的东西 当您从 Feed -> User 导航时,听起来您的 this.props.loadFeed 方法正在覆盖相同的数据。您可以将数据存储在不同的位置吗?这样您就不必担心它会被覆盖。 【参考方案1】:

在堆栈中导航时,React Navigation 不会安装和卸载组件。相反,组件保持安装状态并具有custom react-navigation lifecycle events。

在场景中添加&lt;NavigationEvents&gt; component 是修复用例的一种方法:

import  NavigationEvents  from 'react-navigation';

class PhotoList extends React.Component 
  componentDidMount() 
    this.loadFeed();
  

  loadFeed = () => 
    const  isUser, userId  = this.props;

    // load a single user's photos or all photos
    if (isUser) 
      this.props.loadFeed(userId);
     else     
      this.props.loadFeed();
    
  

  render() 
    return 
      <View>
        <NavigationEvents
          onDidFocus=this.loadFeed
        />
      </View>
    
  

【讨论】:

在不知道如何管理数据的情况下很难推荐一种方法。 loadFeed 的数据去哪了?一个调用会覆盖另一个调用吗? 关于此解决方案的一个注意事项是,调用onDidFocus=this.componentDidMount 可能更有意义,因为无论如何,提要在装载时至少需要加载一次,而不是在此处使用loadFeed ,而只需将逻辑在componentDidMount 这个解决方案的唯一问题是在UserProfile,提要加载了两次。一次进入componentDidMount ,再次进入onDidFocus=this.componentDidMount 我通过从componentDidMountthis.loadFeed 的调用更新了我的代码。我建议不要使用componentDidMount 作为回调;相反,将该逻辑移至另一个函数并从 componentDidMount 调用该函数。 你的函数被称为loadFeed,与prop的loadFeed完全相同,有什么原因吗?询问是因为如果我将其重命名为其他任何名称,我会收到 Can't find variable 错误

以上是关于React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失的主要内容,如果未能解决你的问题,请参考以下文章

注册通知操作不是 React Native 中的函数

使用 Jest 运行 testing-library/react-native 时 RNEncryptedStorage 未定义

使用 react-native-pdf 在 react-native 上获取准确的 x 和 y 坐标

react-native init 指定 react 版本和 react-native 版本

React Native中类“艺术画笔”的重复接口定义

在 react-native.config.js 中检测开发环境