在 react-native-navigation 中,如何在不导航的情况下更新选定的标签栏图标?

In react-native-navigation, how do I update a selected tab bar icon without navigating?

基于屏幕上的操作,我想更新所选选项卡的图标(具体来说,代表 "unread count" 的图标上的徽章装饰器)而无需导航以导致重新呈现。有哪些方法可以做到这一点?

这是使用 tabs template of expo init and then modifying to demonstrate: https://github.com/kevgrig/rn_navigation_badge_updates

问题的基本演示的源代码

这是该回购协议的摘要:https://snack.expo.io/@git/github.com/kevgrig/rn_navigation_badge_updates

关键位是:

我调试了 props.navigation 的可用方法并看到 emit('refocus') 但那没有用。

我用 react-redux 完成了这个。大致是这样的:

import { createStore, applyMiddleware } from 'redux';

import { connect, Provider } from 'react-redux';

const defaultState = {
  badgeCount: 0,
};

const ACTION_REFRESH_STATE = "ACTION_REFRESH_STATE";

function rootReducer(state = defaultState, action) {
  switch (action.type) {
    case ACTION_REFRESH_STATE:
      const result = Object.assign({}, state);
      if (action.new_state.badgeCount) {
        result.badgeCount = action.new_state.badgeCount;
      }
      return result;
    default:
      return state;
  }
}

function refreshState(new_state) {
  return {
    type: ACTION_REFRESH_STATE,
    new_state: new_state,
  };
}

const mapDispatchToProps = (dispatch, ownProps) => {
  return {
    refreshState: (new_state) => {
      dispatch(refreshState(new_state));
    }
  }
};

const store = createStore(rootReducer);

function routeToIcon(routeName) {
  if (routeName.startsWith("Home")) {
    return { iconName: "md-home", mapStateToProps: state => ({ badgeCount: state.badgeCount }) };
  } [...]
}

[...]
    tabBarIcon: ({ focused, horizontal, tintColor }) => {
      const { iconName, mapStateToProps } = routeToIcon(navigation.state.routeName);
      let IconWithBadgeContainer = connect(mapStateToProps, mapDispatchToProps)(IconWithBadge);
      return <IconWithBadgeContainer name={iconName} size={25} color={tintColor} />;
    },
[...]

export default class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppContainer
          ref={navigatorRef => {
            globalNavigatorRef = navigatorRef;
          }}
        />
      </Provider>
    );
  }
}