【问题标题】:Upgrading from React Navigation V4 to V5 redux integration从 React Navigation V4 升级到 V5 redux 集成
【发布时间】:2021-03-01 18:57:55
【问题描述】:

我刚刚获得了一个项目,并被告知要升级所有软件包。目前我正在尝试将 react-navigation 从 V4 升级到 V5,但我遇到了障碍,我无法弄清楚如何在 router.js 的末尾折射代码,或者 ReduxNavigation.jsReducers/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


【解决方案1】:

关于如何在 redux 中存储导航状态的简单答案是不要

当前版本的 React Navigation 使这一点非常明确

我也可以在 Redux 中存储导航状态吗?

这是不可能的。我们不支持它,因为它太容易让自己陷入困境并减慢/破坏您的应用程序。

他们提供了 some advice 关于使用来自 redux 的值将参数传递给 navigate 函数的信息。

您在代码中看到的是旧版本 React Navigation 的一个特性,但总是被建议不要这样做。连version 1.x docs都说

警告!

您可能不需要这样做!如果您不知道自己在做什么,将 React Navigation 状态存储在您自己的 Redux 存储中可能会给您带来非常困难的时期。例如,你会失去一些 React Navigation 可以为你做的性能优化。请不要将你的 state 集成到 Redux 中,除非先确保你可以在没有它的情况下做你需要做的事情!

你需要在你的应用中找到任何从 redux 访问导航状态的地方,并将它们重构为使用 props 和 hooks 直接从 React Navigation 访问它。

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 2020-07-26
    • 2017-09-21
    • 2022-11-17
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多