首页 > 解决方案 > React Native 的功能不会更新状态/不会改变 UI

问题描述

我最近开始创建我的第一个 React Native 应用程序,一切都很顺利,直到我需要根据用户在菜单中按下的按钮来编辑应用程序的状态以呈现不同的页面。我可以通过菜单组件正确调用该函数(toMerchLink)。我什至添加了一个“警报”来测试它是否有效并且确实有效。

下面是我的菜单组件:

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;

这是我的主要 App.js,它根据状态存储要显示的内容的逻辑。抱歉,如果这看起来草率,但我只是想让它工作,一旦我了解更多,我会改进它。

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
  }
});

我一直试图解决这个问题很长一段时间,但我尝试的任何方法似乎都不起作用。这可能是一个非常简单的修复。希望被指出正确的方向。提前致谢!

标签: javascriptreactjsreact-native

解决方案


问题是,选项卡按下处理程序 ( toMerchLink()) 正在更新FooterMenu组件的状态,并且您正在有条件地在组件中渲染App组件。当用户按下选项卡时,您应该更新App组件的状态,而不是组件的状态FooterMenu

因此,更改将传递tabPressHandlerFooterMenu组件,并在用户按 Tab 时调用它。在组件的tabPressHandlerchange state 中App更新 current page

请考虑以下片段

页脚菜单

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>
   );
  }
}

应用程序

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}/>
    }
  }
}

注意:尝试使用任何路由库,导航会容易得多。

希望这会有所帮助!


推荐阅读