如何从React Navigation v3.xx中的选项卡更新自定义tabBarComponent值

问题描述 投票:1回答:1

如何在React Navigation v3.xx中从选项卡更新tabBar值?我有一个自定义的标签栏组件,看起来像

tabBar

我想从标签屏幕更新XXX总值。在屏幕上,我拨打电话以获取余额,成功后我想更新余额,但我不知道如何操作。

class Veggies extends React.Component {
  timer = null;

  state = {
    balance: 0,
    isLoading: false,
  };

  getBalance = () => {
    this.setState({
      isLoading: true,
    });

    this.timer = setTimeout(() => {
      this.setState({
        balance: 200,
        isLoading: false,
      });
    }, 2000);
  };

  render = () => {
    return (
      <View>
        {this.state.isLoading ? (
          <Text>Getting balances...</Text>
        ) : (
          <Text>Your balance: {this.state.balance}</Text>
        )}

        <Button onPress={this.getBalance} title="Get balance" />
      </View>
    );
  };
}

我的自定义标签栏组件

const TabBar = props => {
  const { navigationState, navigation, position } = props;

  return (
    <View>
      <Text>Your total is : XXX</Text>
      <View
        style={{
          height: 80,
          backgroundColor: 'seashell',
          flexDirection: 'row',
          justifyContent: 'space-around',
          alignItems: 'center',
        }}>
        {navigationState.routes.map((route, index) => {
          const focusAnim = position.interpolate({
            inputRange: [index - 1, index, index + 1],
            outputRange: [0, 1, 0],
          });
          return (
            <Tab
              focusAnim={focusAnim}
              title={route.routeName}
              onPress={() => navigation.navigate(route.routeName)}
            />
          );
        })}
      </View>
    </View>
  );
};

这是我的导航器

const TabNavigator = createMaterialTopTabNavigator(
  {
    Vegetables: {
      screen: Veggies,
    },
    Fruits: {
      screen: Fruits,
    },
  },
  {
    tabBarComponent: TabBar,
  }
);

export default createAppContainer(TabNavigator);

我知道我可以通过像redux这样的状态管理库轻松实现这一目标,但是我不想使用任何状态管理库。

Expo snack

react-native react-navigation
1个回答
0
投票

如果您不想使用状态管理库,请使用事件。在TabBar中添加事件侦听器,并在选项卡中发出事件。

import React from 'react';
import { View, Text, Button, DeviceEventEmitter } from 'react-native';

class Veggies extends React.Component {
  timer = null;

  state = {
    balance: 0,
    isLoading: false,
  };

  getBalance = () => {
    this.setState({
      isLoading: true,
    });

    this.timer = setTimeout(() => {
      //emit event here
      DeviceEventEmitter.emit('updateBalance', 200);
      this.setState({
        balance: 200,
        isLoading: false,
      });
    }, 2000);
  };

  render = () => {
    return (
      <View>
        {this.state.isLoading ? (
          <Text>Getting balances...</Text>
        ) : (
          <Text>Your balance: {this.state.balance}</Text>
        )}

        <Button onPress={this.getBalance} title="Get balance" />
      </View>
    );
  };
}

在您的TabBar组件中添加事件侦听器

class TabBar extends React.Component {
  state = {
    balance: 0,
  };

  handleEevent = balance => {
    this.setState({
      balance: balance,
    });
  };

  componentDidMount = () => {
    DeviceEventEmitter.addListener('updateBalance', this.handleEevent);
  };

  componentWillUnmount = () => {
    DeviceEventEmitter.removeListener('updateBalance', this.handleEevent);
  };

  render = () => {
    const { navigationState, navigation, position } = this.props;

    return (
      <SafeAreaView>
        <Text>Your total is : {this.state.balance}</Text>
        <View
          style={{
            height: 80,
            backgroundColor: 'seashell',
            flexDirection: 'row',
            justifyContent: 'space-around',
            alignItems: 'center',
          }}>
          {navigationState.routes.map((route, index) => {
            const focusAnim = position.interpolate({
              inputRange: [index - 1, index, index + 1],
              outputRange: [0, 1, 0],
            });
            return (
              <Tab
                focusAnim={focusAnim}
                title={route.routeName}
                onPress={() => navigation.navigate(route.routeName)}
              />
            );
          })}
        </View>
      </SafeAreaView>
    );
  };
}

Demo

© www.soinside.com 2019 - 2024. All rights reserved.