Как обновить пользовательское значение tabBarComponent из вкладок в реагирующей навигации v3.xx - PullRequest
1 голос
/ 10 апреля 2020

Как обновить значение tabBar из вкладок в реагирующей навигации v3.xx? У меня есть пользовательский компонент панели вкладок, который выглядит как

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

1 Ответ

0 голосов
/ 10 апреля 2020

Если вы не хотите использовать библиотеки управления состоянием, используйте события. Добавьте прослушиватель событий в 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>
    );
  };
}

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...