JRWashington
JRWashington

Reputation: 1

Function for React Native doesn't update the state / doesn't change the UI

I recently started creating my first React Native app and everything has been going well until I needed to edit the state of the app to present a different page depending on what button the user pressed in the menu. I can call the function (toMerchLink) properly via the menu component. I even added an "alert" to test whether it would work and it did.

Below is my menu component:

import React from "react";
import { StyleSheet, Text, View, Butto } from "react-native";
import BottomNavigation, { Tab } from "react-native-material-bottom-navigation";
import Icon from 'react-native-vector-icons/MaterialIcons'

class FooterMenu extends React.Component {

  viewedTab = 0

  toMerchLink = () => {

        this.setState({
            page: 'merch'
          });



        alert('Should go to Merch now.')
        this.viewedTab = 1;
    }

  render() {
    return (
      <BottomNavigation
        activeTab={this.viewedTab}
        labelColor="white"
        rippleColor="white"
        style={{
          height: 56,
          elevation: 8,
          position: "absolute",
          left: 0,
          bottom: 0,
          right: 0
        }}
      >

        <Tab
          barBackgroundColor="#37474F"
          label="Home"
          icon={<Icon size={24} color="white" name="home"/>}

        />
        <Tab
          barBackgroundColor="#00796B"
          label="Merch"
          icon={<Icon size={24} color="white" name="shopping-cart"/>}
          onPress={() => this.toMerchLink()}
        />
        <Tab
          barBackgroundColor="#5D4037"
          label="Settings"
          icon={<Icon size={24} color="white" name="book" />}
        />

      </BottomNavigation>
    );
  }
}

export default FooterMenu;

And this here is my main App.js which stores the the logic of what to show depending on what the state is. Apologies if this looks sloppy, but I am just trying to get this to work, I will improve it once I understand it more.

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import ajax from "./src/ajax";
import CoinList from "./src/components/CoinList";
import FooterMenu from './src/components/Menu';

export default class App extends React.Component {
  /*state = {
    coins: [],
    page: 'merch'
  };*/

  constructor(){
    super();
    this.state = {
      coins: [],
      page: 'home'
    }
}
  async componentDidMount() {
    const coins = await ajax.fetchInitialCoins();
    this.setState({ coins });
  }
  render() {

    if (this.state.page == "home") {
    return (
      <View style={styles.container}>
        {this.state.coins.length > 0 ? (
          <CoinList coins={this.state.coins} />

        ) : (
          <Text style={styles.header}>Simplebits</Text>
        )}
        <FooterMenu />
      </View>
    );

  }

  if (this.state.page == "merch") {
    return (
      <View style={styles.container}>
        <Text>Merch page</Text>
        <FooterMenu />
      </View>
    );

  }

  if (this.state.page == "settings") {
    return (
      <View style={styles.container}>
        <Text>Settings page</Text>
        <FooterMenu />
      </View>
    );

  }

  }

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  header: {
    fontSize: 40
  }
});

I have been trying to figure this out for quite some time, but nothing I tried seems to work. It's likely a really simple fix. Would appreciate being pointed in the right direction. Thanks in advance!

Upvotes: 0

Views: 343

Answers (2)

JRWashington
JRWashington

Reputation: 1

I ended up looking into a routing library as per Prasun Pal's suggestion and I ended up using 'React Navigation' and it took me just a few minutes to implement it and now everything is working perfectly!

Upvotes: 0

Prasun
Prasun

Reputation: 5023

Problem is that, the tab press handler (toMerchLink()) is updating the state of FooterMenu component and you are conditionally rendering component in App component. When user press tab you should updated state of App component, not the state of FooterMenu component.

So the changes will be to pass a tabPressHandler to FooterMenu component, and call it when user press tab. In the tabPressHandler change state of App component to update current page.

Please consider following snippets

FooterMenu

class FooterMenu extends React.Component {
    constructor(props) {
      super(props);
      this.state={ currentTab: 0}
    }
    ...
    render() {
      return (
        <BottomNavigation
          activeTab={this.state.currentTab}
          labelColor="white"
          rippleColor="white"
          style={{
            height: 56,
            elevation: 8,
            position: "absolute",
            left: 0,
            bottom: 0,
            right: 0
          }}
        >
          <Tab
            ...
            onPress={() => {
                this.setState({
                    currentTab: 0
                });
                this.props.onPressHandler('home');
            }}
          />
          <Tab
            ...
            onPress={() => {
                this.setState({
                    currentTab: 1
                });
                this.props.onPressHandler('merch');
            }}
          />
          <Tab
            ...
            onPress={() => {
              this.setState({
                currentTab: 2
              });
              this.props.onPressHandler('settings');
            }}
          />
      </BottomNavigation>
   );
  }
}

App

export default class App extends React.Component {
  ...
  tabPressHandler = (page) => {
    this.setState({
      page
    });
  }
  ...
  render() {
    ...
    if (this.state.page == "merch") {
      ...
      <FooterMenu onPressHandler={this.tabPressHandler}/>
    }
    if (this.state.page == "settings") {
      ...
      <FooterMenu onPressHandler={this.tabPressHandler}/>
    }
  }
}

Note: Try to use any Routing library, navigation would be much easier.

Hope this will help!

Upvotes: 0

Related Questions