我如何通过react导航访问 redux 商店?

IT技术 javascript reactjs react-native redux react-navigation
2021-05-20 04:07:35

我有应用程序“音乐应用程序”供两个用户输入“访客,用户注册”

我有一个底部导航器,当访客打开我的应用程序时,我只想呈现 4 个底部选项卡“主页、浏览、搜索、广播”。

但是当用户登录/注册时,我想呈现 5 个以前的标签以及“库”标签。

所以

我在用户register\login时分派动作,并将 isLogin 状态从false更改true并执行一些操作,例如将一些其他数据添加到我的抽屉中,它看起来不错,

我想访问react-navigation 文件“ Tabs.js ”中的redux 存储

我想访问状态,mapStateToProps但无法this.props.isLogin从非类组件访问

所以我不知道如果我不使用 Class 组件我该怎么做!

那么有没有办法在 Tabs.js 文件中使用“connect HOC”访问 redux 存储?

代码

Tabs.js 文件

import {connect} from 'react-redux';
import {store} from '../redux/store/store';

const LoginTabs = createBottomTabNavigator({....}); // For user '5 tabs'

const notLoginTabs = createBottomTabNavigator({....}); // For Guest '4 tabs'



const App = this.props.isLogin ? LoginTabs : notLoginTabs; // Not work i know :P

export default (createAppContainer(App));

编辑 Drew Reese 的答案

当我尝试以这种方式执行此操作时,我收到了错误消息

const mapStateToProps = state => {
  console.log('state', state);
  return {
    isLogin: state.user.isLogin,
  };
};

const App = ({isLogin, ...props}) =>
  isLogin ? <LoginTabs {...props} /> : <NotLoginTabs {...props} />;
const Root = createAppContainer(App);

export default connect(mapStateToProps)(Root);

错误信息

这个导航器同时拥有导航和容器props,所以不清楚它是否应该拥有自己的状态。移除 props: "isLogin, dispatch" 如果导航器应该从导航 props 获取它的状态。如果导航器应该保持自己的状态,请不要传递导航props。

我试过的

我把所有的堆栈

“抽屉、堆栈、底部标签”

在一个文件“类组件”中,它可以工作,但正如@Drew 所说,这样做不是一个好主意:)

如果你想看,这里有一个要点文件

2个回答

您需要创建动态路由,以及一个根据用户是否登录来呈现选项卡的组件。Tabs.js做以下。

const loginRoutes = {
  Home: {
    screen: Home,
    navigationOptions: {
      title: 'Home',
    },
  },
  Browse: {
    screen: Browse,
    navigationOptions: {
      title: 'Browse',
    },
  },
  Search: {
    screen: Search,
    navigationOptions: {
      title: 'Search',
    },
  },
  Radio: {
    screen: Radio,
    navigationOptions: {
      title: 'Radio',
    },
  },
  Library: {
    screen: Library,
    navigationOptions: {
      title: 'Library',
    },
  },
}

const noLoginRoutes = {
  Home: {
    screen: Home,
    navigationOptions: {
      title: 'Home',
    },
  },
  Browse: {
    screen: Browse,
    navigationOptions: {
      title: 'Browse',
    },
  },
  Search: {
    screen: Search,
    navigationOptions: {
      title: 'Search',
    },
  },
  Radio: {
    screen: Radio,
    navigationOptions: {
      title: 'Radio',
    },
  }
}

const mapStateToProps = state => {
  return {
    isLogin: state.user.isLogin,
 };
};


 const AppNav = ({ isLogin }) => {
  const Container = createAppContainer(
    createDrawerNavigator(
      {
        ...drawerRoutes,
        App: createStackNavigator(
          {
            ...routes,
            Tabs: createBottomTabNavigator(
              isLogin ? loginRoutes : noLoginRoutes
            ),
          },
          routesConfig
        ),
      },
      drawerConfig
    )
  );

  return <Container />;
};

export default connect(mapStateToProps)(AppNav);

演示

我认为您打算制作App一个组件。在这种情况下,它将是一个功能组件,因此没有this,您还需要返回有效的 JSX。

const App = props => props.isLogin ? (
    <LoginTabs {...props} />
  ) : (
    <NotLoginTabs {...props} />
  );

请注意,我已将notLoginTabs组件PascalCased以符合react标准,并将它们作为 JSX 返回并props传播。

如果子组件不关心,isLogin则在传递props之前将其解构。这会清理代码并且不会将不必要的props传递给孩子。

const App = ({ isLogin, ...props }) => isLogin ? (
    <LoginTabs {...props} />
  ) : (
    <NotLoginTabs {...props} />
  );

编辑

创建一个选项卡组件,其中包含经过身份验证和未经身份验证的选项卡。

const LoginTabs = createBottomTabNavigator( ... );
const NotLoginTabs = createBottomTabNavigator( ... );

const Tabs = ({ isLogin, ...props }) => isLogin ? (
    <LoginTabs {...props} />
  ) : (
    <NotLoginTabs {...props} />
  );

const mapStateToProps = state => ({
  isLogin: state.user.isLogin,
});

export default AuthTabs = connect(mapStateToProps)(Tabs)

AppTest

...
const AppNavigator = createStackNavigator(
  {
    TabHome: {
      screen: AuthTabs,
...