react-native - 更新 Redux 状态时,react-navigation StackNavigator 会重置

标签 react-native react-redux react-navigation

这里需要一些帮助,我在使用 redux 和 React 导航时遇到一些问题。

每当我在 redux 中更新状态时,react-navigation 都会重置为我的 DrawerNavigator 中的 initialRouteName,即 Home

this.props.dispatch 更新 Redux 状态后如何留在该屏幕上?

将 redux 与 React-navigation 集成时,我应该执行哪些步骤?

非常感谢您的帮助。欣赏一下

App.js

This is where i declare my StackNavigator, my DrawerNavigator is nested in StackNavigator

import React, { Component } from "react";
import { connect, Provider } from "react-redux";
import { Platform, BackHandler, View, Text } from "react-native";
import { Root, StyleProvider, StatusBar } from "native-base";
import { StackNavigator, NavigationActions } from "react-navigation";

import Drawer from "./Drawer";
import AuthNavigator from "./components/login/authNavigator";

import Home from "./components/home";
import Settings from "./components/settings";
import UserProfile from "./components/userProfile";

import getTheme from "../native-base-theme/components";


const AppNavigator = token => {
    return StackNavigator(
        {
            Drawer: { screen: Drawer },
            Login: { screen: Login },
            Home: { screen: Home },
            AuthNavigator: { screen: AuthNavigator },
            UserProfile: { screen: UserProfile }
        },
        {
            initialRouteName: token ? "Drawer" : "AuthNavigator",
            stateName: "MainNav",
            headerMode: "none"
        }
    );
};

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            isReady: false
        };
    }

    componentDidMount() {
        setTimeout(() => {
            this.setState({ isReady: true });
        }, 500);
    }

    render() {
        let token = null;
        const users = this.props.auth.users;
        const index = this.props.auth.defaultUserIndex;
        if (users.length > 0) {
            token = users[index].token;
        }
        const Layout = AppNavigator(token);
        return (
            <Root>
                <StyleProvider style={getTheme()}>{this.state.isReady ? <Layout /> : <View />}</StyleProvider>
            </Root>
        );
    }
}

var mapStateToProps = state => {
    return {
        auth: state.auth
    };
};

module.exports = connect(mapStateToProps)(App);

Drawer.js

This is my Drawer, whenever i update Redux state, the app will pop back to the initialRouteName of DrawerNavigator which is Home

import React from "react";
import { DrawerNavigator, StackNavigator } from "react-navigation";
import { Dimensions } from "react-native";
import SideBar from "./components/sidebar";

import Home from "./components/home/";
import Settings from "./components/settings/";

const deviceHeight = Dimensions.get("window").height;
const deviceWidth = Dimensions.get("window").width;

const Drawer = DrawerNavigator(
    {
        Home: { screen: Home },
        Settings: { screen: Settings },
        CompanyProfile: { screen: CompanyProfile }
    },
    {
        initialRouteName: "Home",
        contentOptions: {
            activeTintColor: "#e91e63"
        },
        contentComponent: props => <SideBar {...props} />,
        drawerWidth: deviceWidth - 100
    }
);

export default Drawer;

Reducer.js

const defaultState = {
    users: [],
    defaultUserIndex: 0
};

const defaultUserState = {
    phoneNumber: undefined,
    email: undefined,
    name: undefined,
    userId: undefined,
    token: undefined,
    avatar: undefined
};

module.exports = (state = defaultState, action) => {
    console.log("reducer state: ", state);
    switch (action.type) {
        case "AUTH_USER":
        case "UNAUTH_USER":
        case "UPDATE_AVATAR":
        case "UPDATE_PHONENUMBER":
        case "UPDATE_PERSONALDETAILS":
            return { ...state, users: user(state.defaultUserIndex, state.users, action) };

        case "CLEAR_STATE":
            return defaultState;
        default:
            return state;
    }
};

function user(defaultUserIndex, state = [], action) {
    const newState = [...state];
    switch (action.type) {
        case "AUTH_USER":
            return [
                ...state,
                {
                    phoneNumber: action.phoneNumber,
                    name: action.name,
                    email: action.email,
                    userId: action.userId,
                    token: action.token,
                    avatar: action.avatar,
                }
            ];

        case "UNAUTH_USER":
            return state.filter(item => item.token !== action.token);

        case "UPDATE_AVATAR":
            newState[defaultUserIndex].avatar = action.avatar;
            return newState;

        case "UPDATE_PERSONALDETAILS":
            newState[defaultUserIndex].name = action.name;
            newState[defaultUserIndex].email = action.email;
            return newState;
        default:
            return state;
    }
}

最佳答案

在您的情况下:您在每次渲染调用时创建新的AppNavigator。每个实例都有新的导航状态。

您可以通过将初始化移动到构造函数来修复它,因此每次下一个渲染都将使用相同的对象。

constructor(props) {
    super(props);

    this.state = {
        isReady: false
    };
    const token = //sometihng
    this.navigator =  AppNavigator(token)
}

另外:探索官方文档中 redux 集成的示例 https://github.com/react-community/react-navigation/blob/master/docs/guides/Redux-Integration.md

关于react-native - 更新 Redux 状态时,react-navigation StackNavigator 会重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47809027/

相关文章:

reactjs - 我如何构建这个 React Native 部分列表实现

jestjs - 如何在react-navigation 5.0中模拟useNavigation Hook 以进行 Jest 测试?

react-navigation - 在标题选项中使用 UIKitten 图标 react 导航 5

java - 使用 firebase java.lang.NoClassDefFoundError : Failed resolution of: Lcom/google/android/gms/common/internal/zzbq react native

javascript - 无需渲染命令的 React-Native 导航

javascript - 当您过滤时, foreach 不适用于对象数组

android - 使用 React-Navigation 在所有屏幕中显示组件 - React Native

javascript - React 组件访问共享点

javascript - 如何在reactjs中更新挂载状态

javascript - 使用react-native构建android应用程序时如何解决命令节点问题?