在反应原生导航中,如何在不导航的情况下更新选定的标签栏图标?



根据屏幕上的操作,我想更新所选选项卡的图标(特别是图标上的徽章装饰器,表示"未读计数"(,而无需导航以导致重新渲染。有哪些方法可以做到这一点?

以下是使用expo init选项卡模板进行问题的基本演示的源代码,然后进行修改以演示: https://github.com/kevgrig/rn_navigation_badge_updates

这是该回购的小吃:https://snack.expo.io/@git/github.com/kevgrig/rn_navigation_badge_updates

关键位是:

  • 导航/MainTabNavigator 中的createBottomTabNavigator.js带有返回<TabBarIcon />组件并传递badgeCount参数的tabBarIcons。

    let homeTabCount = 1;
    HomeStack.navigationOptions = {
    tabBarLabel: 'Home',
    tabBarIcon: ({ focused }) => {
    return (
    <TabBarIcon
    focused={focused}
    name={
    Platform.OS === 'ios'
    ? `ios-information-circle${focused ? '' : '-outline'}`
    : 'md-information-circle'
    }
    badgeCount={homeTabCount}
    />
    );
    },
    };
    
  • 组件/TabBarIcon 中的TabBarIcon组件.js带有可选的badgeCount参数。

    export default class TabBarIcon extends React.Component {
    render() {
    const { name, focused, badgeCount } = this.props;
    return (
    <View style={badgeStyles.badgeView}>
    <Ionicons
    name={name}
    size={26}
    style={{ marginBottom: -3 }}
    color={focused ? Colors.tabIconSelected : Colors.tabIconDefault}
    />
    { badgeCount > 0 && (
    <View style={badgeStyles.badgeContainer}>
    <Text style={badgeStyles.badgeText}>{badgeCount}</Text>
    </View>
    )}
    </View>
    );
    }
    }
    
  • 屏幕
  • /主屏幕中主屏幕上的一个Button.js带有一个onPress处理程序,我想用它来更新主屏幕选项卡的badgeCount

    export default class HomeScreen extends React.Component {
    onPress = () => {
    // TODO - how to update the badgeCount?
    }
    

我调试了可用的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>
);
}
}

相关内容

最新更新