javascript - React Native 应用程序中 Redux thunk 的奇怪行为

标签 javascript reactjs react-native redux react-navigation

我最近在我的应用程序中注意到 Redux 的一个非常奇怪的行为,我想与您分享。当我在我的设置中单击此 TouchableOpacity 以断开连接时,出现以下错误:

TypeError: Cannot read property first_name of null

来自 Homepage.js

所以我的代码为我不应该去的页面中的那个组件触发了一个错误。

Homepage.js

<AppText textStyle={styles.title}>
  Welcome {userReducer.infos.first_name}
</AppText>

应该发生的工作流是用户单击断开连接按钮,然后调用 tryLogout 函数,它触发类型为“LOGOUT”的操作。然后此操作使用一些额外的 bool 值将用户相关数据和信息设置为空。状态得到更新,然后应该重新渲染 UI 并调用 componentWillUpdate()。在那里,我检查我的状态以将用户重定向到着陆/未连接的导航。

我尝试在我的 reducer 中注释 infos: null 并且我的代码处理没有错误。

这个变量在我的应用程序中没有任何地方要求重定向到任何页面。

调试起来可能看起来很复杂,因为问题一定比看起来更深。无论如何,也许有人已经遇到过类似的问题,所以我在这里为您提供尝试解决该问题的潜在要素。

Settings.js

import { tryLogout } from '@actions/user'

const mapDispatchToProps = dispatch => ({
  tryLogout: () => dispatch(tryLogout()),
})

class Settings extends React.Component<Props, State> {  

  // What should normally happen
  componentDidUpdate(prevProps: Props) {
      const { userReducer, navigation } = this.props

      if (
        prevProps.userReducer.isSignedUp !== userReducer.isSignedUp ||
        prevProps.userReducer.isLoggedIn !== userReducer.isLoggedIn
      ) {
        if (!userReducer.isSignedUp && !userReducer.isLoggedIn) {
          navigation.navigate('Landing')
        }
      }
    }

  // Inside my render() method
  <AppTouchableOpacity
          onPress={() => tryLogout()}
          style={styles.touchableOpacity}
        >
          Disconnect
  </AppTouchableOpacity>
}

actions/user.js

export const tryLogout = (): Function => (dispatch: Function) => {
  const logout = () => ({
    type: LOGOUT,
  })

  dispatch(logout())
}

reducers/user.js

case LOGOUT:
  return {
    ...state,
    data: null,
    infos: null,
    isLoggedIn: false,
    isSignedUp: false,
  }

App.js(我正在使用 React Navigation)

const LandingScenes = {
  Welcome: { screen: WelcomeScreen },
  { /* Some other screens */ }
}

const LandingNavigator = createStackNavigator(LandingScenes, {
  initialRouteName: 'Welcome',
  defaultNavigationOptions: {
    header: null,
  },
})

const SecuredScenes = {
  Homepage: { screen: HomepageScreen },
  Settings: { screen: SettingsScreen },
  { /* Some other screens */ }
}
const SecuredNavigator = createStackNavigator(SecuredScenes, {
  initialRouteName: 'Homepage',
  defaultNavigationOptions: {
    header: null,
  },
})

export default createAppContainer(
  createSwitchNavigator(
    {
      Landing: LandingNavigator,
      Secured: SecuredNavigator,
    },
    {
      initialRouteName: 'Landing',
    }
  )
)

最佳答案

当'infos'的值为空时,听起来它正在尝试渲染。

这是有道理的,因为主屏幕仍然存在于主内存中,在您的导航堆栈中,这是因为您在导航到设置时使用了“导航”方法。

所以这是使用 react-navigation 而不是 redux 或 redux thunk 的结果。

要在您的 View 中处理此错误情况,除非定义了信息,否则您无法呈现文本。就像下面的例子一样,你当然可以显示一个加载程序,或者如果信息是未定义/空的,而不是什么都没有,甚至是默认消息。

真的,这里的最终答案是重组您的导航。您可以考虑使用不同的方法导航到设置页面,这会重置堆栈导航器,或者将其保留在 View 中,这两种方法都是理想的。

例如,查看 replace 方法,它用于重置导航堆栈,甚至查看切换导航器,它只显示一个屏幕(屏幕可以是堆栈导航器,即多个屏幕)一次,在您的应用程序中创建上下文之间的分离。

{userReducer.infos && (
     <AppText textStyle={styles.title}>
       Welcome {userReducer.infos.first_name}
     </AppText>
)}

关于javascript - React Native 应用程序中 Redux thunk 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56027012/

相关文章:

javascript - 递归 promise 创建树

javascript - 自定义 jquery ui slider

javascript - 从与脚本相同的文件夹中获取文件

reactjs - React Router 防止随机路由

react-native - 在根项目 'installRelease' 中找不到任务 'ReactNativeStarter'。一些候选人是 : 'uninstallRelease'

javascript - 根据浏览器运行不同的 JavaScript

javascript - React - 在渲染期间更新状态会产生错误

javascript - 如果另一个元素为空则隐藏元素

javascript - 找不到变量 : StyleSheet

javascript - 将值从数组传递给 React Native 中的函数