我现在基本上正在清理我的代码,发现一些奇怪的东西,我发现mapStateToProps
和connect
在该文件中的任何地方都没有使用:
import React from 'react';
import { Scene, Router, ActionConst, Stack } from 'react-native-router-flux';
import { connect } from 'react-redux'; //HERE
import { AsyncStorage } from 'react-native';
//import components for scenes
import Splash from '../components/Splash/Splash';
import Login from '../modules/auth/scenes/Login';
import Home from '../modules/home/scenes/Home';
import itemDescription from '../modules/home/scenes/itemDescription';
import About from '../modules/home/scenes/About';
import Setting from '../modules/home/scenes/Setting';
import NavDrawer from '../modules/home/components/NavDrawer';
//Import Store, actions
import store from '../redux/store'
import * as t from '../modules/auth/actionTypes';
export const mapStateToProps = state => ({ //HERE
isLoggedIn: state.authReducer.isLoggedIn
});
class Routes extends React.Component {
constructor() {
super();
this.state = {
isReady: false,
isLoggedIn: false,
userName:""
}
}
componentDidMount() {
//load token from async and put it in redux's state
AsyncStorage.getItem('token').then((data) => {
setTimeout(() => {
if (data !== null) {
this.setState({ isReady: true, isLoggedIn: true });
store.dispatch({ type: t.LOGGED_IN, token: data });
}
else {
this.setState({ isReady: true, isLoggedIn: false })
store.dispatch({ type: t.LOGGED_OUT });
}
}, 5000)
});
//load username from async storage and put it in route's state to be passed to drawer as props
AsyncStorage.getItem('username').then(name => {
this.setState({ userName: name.charAt(0).toUpperCase() + name.slice(1) });
});
}
render() {
if (!this.state.isReady)
return <Splash />
return (
<Router>
<Scene key="root" hideNavBar>
<Stack key="Auth" initial={!this.state.isLoggedIn}>
<Scene key="Login" hideNavBar component={Login} title="Login" />
</Stack>
<Stack key="Main" initial={this.state.isLoggedIn}>
<Scene drawer key="NavDrawer" hideNavBar contentComponent={()=><NavDrawer username={this.state.userName}/>} type={ActionConst.REPLACE} panHandlers={null}>
<Scene key="homeTab" title="Home" drawerLockMode={'locked-closed'}>
<Scene key="Home" hideNavBar component={Home} title={"Home"} />
<Scene key="itemDescription" hideNavBar component={itemDescription} title="Item Description" back />
</Scene>
<Scene key="aboutTab" title="About" drawerLockMode={'locked-closed'}>
<Scene key="About" hideNavBar component={About} title={"About"} />
</Scene>
<Scene key="settingTab" title="Settings" drawerLockMode={'locked-closed'}>
<Scene key="Setting" hideNavBar component={Setting} title={"Setting"} />
</Scene>
</Scene>
</Stack>
</Scene>
</Router>
)
}
}
export default connect(mapStateToProps)(Routes) //HERE
我很确定这些来自我早期的开发,但我还没有删除,但是,当我尝试删除这3条标记的行,并且只是单独导出默认路由时,发生了一些奇怪的事情:
登录后键盘不会消失
依赖于存储在redux状态的令牌的主屏幕数据突然没有获取(获取失败)
用户名无法加载到抽屉上。
据我所知mapStateToProps
仅用于将redux的状态映射到链接的(使用connect
)组件的prop,以便组件可以访问它们。
它应该是一个只读机制,因为我在store.dispatch
componentDidMount
设置了redux的状态
对于为什么会发生这种情况,您会猜到什么?我在这里理解错了吗?
老实说,我不知道在哪里看:(
提前感谢任何想法!
更新:我发现上述代码段中的store.dispatch
由于某种原因我删除mapStateToProps
时没有按时更新令牌,使我的主页无法从其中获取数据componentDidMount()
因为令牌仍为空。但是,在Home的生命周期的下一次迭代中,控制台日志显示令牌已更新,但更新后未调用componentDidMount,而是之前。问题仍然存在,为什么mapStateToProps
在这种情况下很重要?
答案 0 :(得分:0)
在整个应用程序中进行一些控制台记录后,我终于知道了mapStateToProps在这种情况下的原因。 所以看起来场景就像这样:
with mapStateToProps:
路线加载令牌 - &gt;发送令牌以存储并开始加载家庭 - &gt; home componentDidMount
已触发但令牌仍为null,因为未执行调度 - &gt;一旦完成调度,路由将被重新安装,因为它订阅了使用调度进行更新的mapStateToProp - &gt; home重新加载,这次令牌就在那里
不
路线加载令牌 - &gt;发送令牌以存储并开始加载家庭 - &gt; home componentDidMount
已触发但令牌仍为null,因为未执行调度 - &gt;完成调度后,路由不会重新安装,因为它没有订阅使用调度更新的mapStateToProps - &gt;家没有重新加载
所以看来我的应用程序正在运行,但出于完全错误的原因!!
因此,在我删除mapStateToProps
以使我的应用程序在逻辑上合理之后,在我的问题中,它从代码段中的这两个连续行开始:
this.setState({ isReady: true, isLoggedIn: true });
store.dispatch({ type: t.LOGGED_IN, token: data });
这两行在比赛中是 并且序列已经开始关闭,我应该首先dispatched
然后将状态设置为isReady:true
,这更有意义比上面的片段,因为当我甚至没有将令牌发送到商店时,我怎么能说“嘿,你可以解雇Splash屏幕并开始装回家”!
但即便如此,这两条线仍在竞赛,因为它们都是异步操作,所以现在我唯一的问题是如何解决这个race condition
,这更容易理解! :d