我最近注意到我想与您分享Redux在我的应用程序中的异常行为。当我在设置中单击此TouchableOpacity以断开连接时,出现以下错误:
TypeError:无法读取null的属性first_name
来自Homepage.js
因此,我的代码针对我不应该去的页面中的那个部件触发了错误。
Homepage.js
<AppText textStyle={styles.title}>
Welcome {userReducer.infos.first_name}
</AppText>
应该执行的工作流程是用户单击断开连接按钮,然后调用tryLogout函数,该函数将触发类型为“ LOGOUT”的操作。然后,此操作将使用一些其他布尔值的用户相关数据和信息设置为空。更新状态后,应重新呈现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',
}
)
)
答案 0 :(得分:1)
如果我的理解正确,那么问题是用户退出时预计不会加载Homepage
组件,但是会在null
上抛出infos
错误。由于您使用的是堆栈导航器,因此您的Homepage组件实际上仍可能安装在堆栈中。您将需要处理null
中的Homepage
情况,或者在导航到Settings
的过程中将其从堆栈中删除。
您可以在Navigation lifecycle - Example scenario的文档中找到有关反应导航的生命周期的更多详细信息,重要的部分在此处:
我们从主屏幕开始,然后导航到DetailsScreen。然后,我们使用选项卡栏切换到SettingsScreen并导航到ProfileScreen。完成此一系列操作后,所有4个屏幕均已安装!
答案 1 :(得分:1)
当'infos'的值为null时,听起来像是尝试渲染的声音。
这很有意义,因为主屏幕仍位于导航堆栈中的主内存中,这是因为导航至设置时正在使用“导航”方法。
所以这是使用react-navigation而不是redux或redux thunk的结果。
要在您的视图中处理此错误情况,除非定义了信息,否则无法渲染文本。像下面的示例一样,您当然可以显示一个加载程序,或者如果infos是undefined / null,那么什么都可以显示,而不是什么也不显示,甚至是默认消息。
真的,这里的最终答案是重组导航。您可能会考虑使用另一种方法导航到设置页面,该页面将重置堆栈导航器,或者将其保持在视图中,这两者都是理想的选择。
例如,查看replace方法,该方法用于重置导航堆栈,甚至查看switch导航器,后者仅显示一个屏幕(其中一个屏幕可以是堆栈导航器,即多个屏幕)一次,在您的应用程序内的上下文之间创建分隔。
{userReducer.infos && (
<AppText textStyle={styles.title}>
Welcome {userReducer.infos.first_name}
</AppText>
)}