当redux状态更改时更改tabBarIcon

时间:2020-01-26 11:00:06

标签: react-native react-redux

我在navigationOptions下为以下流程定义了App.js

App.js

const intimationsFlow = createStackNavigator({
  Feed: FeedContainer,
  Edit: EditContainer
});

intimationsFlow.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  if (navigation.state.index > 0)
    tabBarVisible = false;

  return {
    title: '',
    tabBarIcon: ({ focused }) => {
      const { pushNotificationSeen } = store.getState();
      console.log('pushNotificationSeen', pushNotificationSeen);

      let i;
      if(pushNotificationSeen) {
        if (focused) {
          i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />
        } else {
          i = <FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />
        }
      } else {
        if (focused) {
          updatePushNotificationSeen(true);
          i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />
        } else {
          i = <><FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} /><Badge status="error" badgeStyle={{ position: 'absolute', top: -26, right: -13 }} /></>
        }
      }

      return i;
    },
    tabBarVisible
  };
};

const AppNavigator = createSwitchNavigator({
  ResolveAuth: ResolveAuthScreen,
  mainFlow
});

const App = createAppContainer(AppNavigator);

export default () => {
  return <Provider store={store}>
    <SafeAreaProvider>
      <App ref={navigatorRef => { setTopLevelNavigator(navigatorRef) }} />
    </SafeAreaProvider>
  </Provider>
}; 

我想基于是否已经看到推送通知来更新tabBarIcon。如果尚未看到推送通知,那么我将显示一个徽章。

这里的问题是,我只能在选项卡栏上有活动时才能获取状态。但是我想要的是,每当pushNotificationSeen的状态更新时,tarBarIcon都应该重新呈现。

请建议是否有可能,否则如何实现。谢谢。

2 个答案:

答案 0 :(得分:0)

您必须在componentWillReceiveProps上监听化简器中的推送通知更改

class YourComponent extends React.Component {
    {...}
    static navigationOptions = {
        title: ({ state }) => `there is ${state.params && state.params.pushNotificationSeen ? state.params.pushNotificationSeen : ''}`,
        {...}
    }
    {...}
    componentWillReceiveProps(nextProps) {
        if (nextProps.pushNotificationSeen) {
            this.props.navigation.setParams({ pushNotificationSeen });
        }
    }
}

const connectedSuperMan = connect(state => ({ pushNotificationSeen: state.ReducerYo.pushNotificationSeen }))(YourComponent);

答案 1 :(得分:0)

我能够找到一个不错的解决方案。

我真正想要的是一种从 React Navigation组件访问redux存储的方法。像其他任何React组件一样,React导航组件也可以connected到redux存储。但是,在这种情况下,为了连接react导航组件,我想要的是根据此custom extended navigator创建一个suggestion

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Badge } from 'react-native-elements';
import { createStackNavigator } from 'react-navigation-stack';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { NavigationEvents } from 'react-navigation';

import FeedContainer from '../../screens/feed/FeedContainer';
import EditContainer from '../../screens/edit/EditContainer';
import { updatePushNotificationSeen } from '../../store/push-notification-seen/actions';

const IntimationsFlow = createStackNavigator({
    Feed: FeedContainer,
    Edit: EditContainer
});

class IntimationsFlowNavigator extends Component {

    static router = IntimationsFlow.router;

    static navigationOptions = ({ navigation }) => {
        let tabBarVisible = true;
        if (navigation.state.index > 0)
            tabBarVisible = false;

        return {
            title: '',
            tabBarIcon: ({ focused }) => {
                let i;
                if (!navigation.state.params || navigation.state.params.pushNotificationSeen) {
                    if (focused)
                        i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />;
                    else
                        i = <FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />;
                } else {
                    if (focused)
                        i = <FontAwesomeIcon icon={'bell'} size={29} color={'#3780BE'} />;
                    else
                        i = <>
                            <FontAwesomeIcon icon={'bell'} size={29} color={'#393939'} />
                            <Badge status="error" badgeStyle={{ position: 'absolute', top: -26, right: -13 }} />
                        </>;
                }

                return i;
            },
            tabBarVisible
        };
    };

    componentDidUpdate(prevProps) {
        const { navigation, pushNotificationSeen } = this.props;
        if (pushNotificationSeen !== prevProps.pushNotificationSeen)
            navigation.setParams({ pushNotificationSeen });
    }

    render() {
        const { navigation } = this.props;
        return <>
            <NavigationEvents
                onDidFocus={() => { if (!this.props.pushNotificationSeen) updatePushNotificationSeen(true) }}
                onDidBlur={() => { if (!this.props.pushNotificationSeen) updatePushNotificationSeen(true) }}
            />
            <IntimationsFlow navigation={navigation} />
        </>;
    }
}

const mapStateToProps = ({ pushNotificationSeen }) => {
    return { pushNotificationSeen };
};

export default connect(mapStateToProps, null)(IntimationsFlowNavigator);

每次道具都有更新。我正在navigation.state.params.pushNotificationSeen lifecycle method中为navigation.setParams({ pushNotificationSeen });设置新的值,以便在componentDidUpdate静态方法中使用它。 (由于它是静态成员,因此我们无法直接在navigationOptions方法中访问组件props)。

根据NavigationEvents,可以通过suggestion来实现需要在标签的焦点/模糊上执行的任何副作用。