【发布时间】:2019-08-29 21:52:30
【问题描述】:
在我的工作中,我们正在使用 Expo 创建一个 RN 应用程序,我们目前使用 react-navigation 来满足我们的路由需求。我们目前正在尝试迁移到使用 react-native-router-flux,因为它允许 uriPrefix => app Deep Linking 开箱即用,并且似乎是满足我们公司需求的整体更好的解决方案。我们已经查看了 react-native-router-flux repo 中的 Expo 示例代码并进行了相应的操作。
我们遇到的问题是任何时候全局状态更改(我们正在结合 Context API 和 React Hooks 来创建一个位于 App.js 之上的全局 StateProvider。请参阅:https://medium.com/simply/state-management-with-react-hooks-and-context-api-at-10-lines-of-code-baf6be8302c)使用调度程序操作,整个应用程序重置本身并将您带回初始主屏幕。在此之前,我们使用 npm reactn 来管理各种全局状态,因为我们想尝试避免繁重/乏味的 redux 设置。有没有其他人遇到过这样的问题,每次全局状态发生变化时,整个应用程序都会自行刷新(而不是进行 vDOM 比较并仅重新呈现已更改的内容)。使用 react-navigation 进行路由时,我们看不到这种行为。
const defaultReducer = new Reducer(params);
return (state, action) => {
console.log(`reducer: ${action.type} ${action.routeName}`);
return defaultReducer(state, action);
};
};
const stateHandler = (prevState, newState, action) => {
console.log('onStateChange: ACTION:', action);
};
const getSceneStyle = () => ({
backgroundColor: '#F5FCFF',
shadowOpacity: 1,
shadowRadius: 3,
});
const drawerImg = () => {
return (
<Image
source={require('../../assets/images/icon-img.png')}
style={{
height: 63,
width: 63,
marginLeft: 5,
marginBottom: 5,
marginTop: 5,
}}
/>
);
};
// on Android, the URI prefix typically contains a host in addition to scheme
const prefix = Platform.OS === 'android' ? 'myApp://myApp/' : 'myApp://';
const transitionConfig = () => ({
screenInterpolator: StackViewStyleInterpolator.forFadeFromBottomAndroid,
});
export const AppNavigator = React.forwardRef(() => (
<Router
createReducer={reducerCreate}
onStateChange={stateHandler}
getSceneStyle={getSceneStyle}
uriPrefix={prefix}
>
<Overlay key="overlay">
<Modal key="modal" hideNavBar transitionConfig={transitionConfig}>
<Lightbox key="lightbox">
<Stack
key="root"
hideNavBar
titleStyle={{ alignSelf: 'center' }}
navigationBarStyle={{ backgroundColor: themeColor }}
>
<Drawer
hideNavBar
key="drawer"
onExit={() => {
console.log('Drawer closed');
}}
onEnter={() => {
console.log('Drawer opened');
}}
// drawerImage={drawerImg}
contentComponent={DrawerContent}
drawerWidth={300}
>
<Scene hideNavBar>
<Tabs key="tabbar" swipeEnabled>
<Scene
initial
key={`homeStack`}
title={`Home`}
icon={({ focused }) => (
<CustomIcon name="home" size={24} focused={focused} />
)}
>
<Scene key={`homeScreen`} component={HomeScreen} />
</Scene>
<Scene
key={`communityStack`}
title={`Communities`}
icon={({ focused }) => (
<CustomIcon name={`group`} size={24} focused={focused} />
)}
>
<Scene key={`communityList`} component={CommunityList} />
<Scene key={`communityFeed`} component={CommunityFeed} />
</Scene>
<Scene
key={`notificationStack`}
title={`Notifications`}
icon={({ focused }) => (
<CustomIcon
name={`notifications`}
size={24}
focused={focused}
/>
)}
>
<Scene
key="notifications"
// component={Test}
component={NotificationsScreen}
/>
</Scene>
<Scene
key={`profileStack`}
title={`Profile`}
icon={({ focused }) => (
<CustomIcon name={`profile`} size={20} focused={focused} />
)}
>
<Scene key="profile" component={OwnProfileScreen} />
</Scene>
</Tabs>
</Scene>
</Drawer>
</Stack>
</Lightbox>
</Modal>
</Overlay>
</Router>
));
// this is what the dispatcher action looks like in componentDidMount of one of the components.
componentDidMount = async () => {
console.log(`mounting homescreen.js`);
// this causes infinite refresh
const [_, dispatch] = this.context;
const storedKeys = await _getAllStoredKeys();
if (!storedKeys.find(key => key === `currentUser`)) {
console.log(`no currentUser in cache, redirecting to login`);
} else {
var res = await _getStoredItem(`currentUser`);
dispatch({ type: SET_USER, setUser: res });
}
};
当按下选项卡以导航到与 homeStack 屏幕(初始路线)不同的屏幕时,我希望屏幕能够正确渲染和设置,实际发生的是屏幕已安装(通过 console.log() 确认在 componentDidMount()) 中,然后将用户返回到 homeStack 的初始场景。
【问题讨论】:
标签: reactjs react-native expo react-native-router-flux react-context