【发布时间】:2021-03-01 18:57:55
【问题描述】:
我刚刚获得了一个项目,并被告知要升级所有软件包。目前我正在尝试将 react-navigation 从 V4 升级到 V5,但我遇到了障碍,我无法弄清楚如何在 router.js 的末尾折射代码,或者 ReduxNavigation.js 和 Reducers/NavigationReducer.js 中的代码
旧 router.js(代码移到下面的app.tsx)
const defaultNavigationOptions = {
defaultNavigationOptions: {
headerStyle: ComponentStyles.Navigation.header,
}
}
const modalNavigatorConfig = {
cardStyle: {
opacity: 1
},
navigationOptions: {
initialRouteName: 'Authentication',
headerMode: 'screen'
}
}
const authStack = createStackNavigator(
{
Login: LoginScreen,
}, defaultNavigationOptions
)
const dashboardStack = createStackNavigator({
Dashboard: DashboardScreen,
}, defaultNavigationOptions)
const appStack = createBottomTabNavigator({
Dashboard: {
screen: dashboardStack,
navigationOptions: {
title: "Dashboard",
tabBarIcon: ({focused, tintColor}) => (
<Image
resizeMode='contain'
style={{width: 24, height: 24, tintColor: (focused ? null : tintColor) }}
source={require('@Images/tab-dashboard.png')}
/>
)
}
},
})
export const ModalStack = createSwitchNavigator(
{
Authentication: authStack,
App: appStack,
},
{
initialRouteName: 'Login',
...defaultNavigationOptions
}
)
// Unsure of how to refractor this in V5 <---------------------
export const ReactNavigationReduxMiddleware = createReactNavigationReduxMiddleware(
state => state.nav
)
export const App = createReduxContainer(ModalStack, 'root')
const mapStateToProps = state => ({
state: state.nav
})
const AppWithNavigationState = connect(mapStateToProps)(App)
export default AppWithNavigationState
App.tsx(路由器在 app.tsx 中,因为我不知道如何将它放在单独的 router.js 文件中)
const appStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function appStack() {
return (
<appStack.Navigator initialRouteName="Authentication">
<appStack.Screen name="Authentication" component={AuthLoadingScreen} options={{headerShown: false}} />
<appStack.Screen name="Login" component={LoginScreen} options={{headerShown: false}} />
<appStack.Screen name="Dashboard" component={DashboardScreen} />
</DashboardStack.Navigator>
);
}
function TabsStack() {
return (
<Tab.Navigator>
<Tab.Screen
name="Dashboard"
component={appStack}
options={{
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
)
}
const App = () => {
return (
<>
<Provider store={store}>
<StatusBar barStyle="dark-content" />
<NavigationContainer>
<TabsStack />
</NavigationContainer>
</Provider>
</>
);
};
export default App;
我不确定如何折射这个。在 V5 中甚至可能吗?
ReduxNavigation.js
class ReduxNavigation extends React.Component {
componentDidMount() {
BackHandler.addEventListener("hardwareBackPress", this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", this.onBackPress);
}
onBackPress = () => {
const { nav, dispatch } = this.props;
if (nav.index === 0) {
return false;
}
if (nav.routes) {
const currentRouteName = nav.routes[nav.index].routeName;
if (currentRouteName === 'PAudit' || currentRouteName === 'PInit') {
return true;
}
}
dispatch(NavigationActions.back());
return true;
};
render() {
const { nav, dispatch } = this.props;
return <App state={nav} dispatch={dispatch} />;
}
}
const mapStateToProps = state => ({
nav: state.nav
});
export default connect(mapStateToProps)(ReduxNavigation);
Reducers/NavigationReducer.js(getActionForPathAndParams 在 V5 中已弃用,我找不到类似的功能)
import { ModalStack } from '@Components/Router'
const { router } = ModalStack
const firstAction = router.getActionForPathAndParams('Authentication') // getActionForPathAndParams is deprecated in V5
const tempNavState = router.getStateForAction(firstAction)
/* ------------- Initial State ------------- */
export const INITIAL_STATE = router.getStateForAction(tempNavState)
export const reducer = (state = INITIAL_STATE, action) => {
const nextState = router.getStateForAction(action, state)
// Simply return the original `state` if `nextState` is null or undefined.
return nextState || state
}
export default reducer
商店
export default store = Reactotron.createStore(
rootReducer,
{},
compose(
applyMiddleware(ReduxThunk),
applyMiddleware(ReactNavigationReduxMiddleware)
)
)
reducers/index.js
const appReducer = combineReducers({
nav: NavigationReducer,
})
const { Types, Creators: Actions } = createActions({
resetApp: []
})
const rootReducer = createReducer([], {
[Types.RESET_APP]: (state, action) => {
return appReducer(undefined, action)
//Passing undefined as state will make all the reducers using their initial states.
},
[ReduxSauceTypes.DEFAULT]: (state, action) => {
return appReducer(state, action)
}
})
const resetReduxStore = () => {
return dispatch => {
dispatch(Actions.resetApp())
}
}
export { rootReducer, resetReduxStore }
package.json
"react-navigation": "^4.4.3",
"react-navigation-redux-helpers": "^4.0.1",
"react-navigation-stack": "^2.10.2",
"react-navigation-tabs": "^2.10.1",
"redux": "^4.0.1",
"react-redux": "^7.2.2",
"redux-persist": "^5.6.6",
"redux-thunk": "^2.2.0",
"reduxsauce": "^0.7.0",
【问题讨论】:
-
这里有很多代码,但如果你能解释一下通过集成 Redux 和 React Navigation 而不是单独使用两者来实现的目标,那将会很有帮助。
-
@LindaPaiste 我是 React 新手。我只是被告知升级软件包。我没有写原始代码。独立使用它们会更好吗?有什么区别?
标签: react-native redux react-redux react-navigation