React Native组件不会在状态更改时重新呈现

时间:2019-10-01 10:52:35

标签: javascript react-native react-native-android

无论我尝试什么,我似乎都无法更新我的组件。下面是我的代码:

@Html.TextBoxFor(m => m.foo, new {   type = "checkbox" })

奇怪的是,我在两个不同的屏幕中使用了此组件,在一种情况下,它绝对可以正常工作,但是在另一种屏幕中,当更改音频时,它不会重新呈现。

每次我按下它时道具都会更新,所以我知道状态会更新。控制台日志总是写出不同的状态,因此我知道状态已更新。我还尝试了import React, { Component } from "react"; import { StyleSheet, View, TouchableOpacity, Image, Text } from "react-native"; import PropTypes from "prop-types"; import { toggleSound } from "logic/Music.js"; import soundOn from "assets/img/swipe.png"; import soundOff from "assets/img/illum-triangle.png"; export default class GlobalSoundButton extends Component { constructor(props) { super(props); this.state = { audioOff: this.props.audioOff }; } componentDidUpdate = prevProps => { if (prevProps.audioOff !== this.props.audioOff) { this.setState({ audioOff: this.props.audioOff }, () => { console.log("SWITCHING STATE", this.state); }; this.forceUpdate(); } }; render() { return ( <View style={styles.soundButtonWrapper} key={this.props.name}> <TouchableOpacity style={styles.soundButtonPress} activeOpacity={0.8} onPress={() => { toggleSound(this.props.sounds); }} > <Image style={styles.soundButton} source={this.state.audioOff ? soundOff : soundOn} ></Image> <Text style={styles.text}> Audio {this.state.audioOff ? "off" : "on"} </Text> </TouchableOpacity> </View> ); } } const styles = StyleSheet.create({ soundButtonWrapper: { width: "100%", height: 40, position: "absolute", top: 20 }, soundButtonPress: { width: 40, height: 40, position: "absolute", right: 20 }, soundButton: { width: 40, height: 40, tintColor: "#59BC92" }, text: { width: 120, height: 40, position: "absolute", right: 80, color: "white" } }); GlobalSoundButton.propTypes = { sounds: PropTypes.array }; 并添加了一个密钥(您可以在代码中看到该密钥),但这无济于事。

我在这里不知所措。有没有人遇到同样的问题或可以提供帮助?我也知道有几个类似的问题,但是没人回答我的问题,所以我不得不自己写。

我在这里删除了许多无关的代码,但基本上我是通过以下方式在HomeScreen中传递道具的(它是forceUpdate() ,在这种情况下它可以工作):

GlobalSoundButton

我其他组件无法正常工作的区别是这样呈现的:

import GLOBAL from "logic/GlobalState.js";

export default class HomeScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      audioOff: false,
    };
  }

  async componentDidMount() {
    let audioOff;
    try {
      audioOff = await retrieveData("audioOff");
    } catch (err) {
      console.error(err);
    }

    this.setState(
      {
        audioOff: audioOff === "true"
      });

  render() {
    GLOBAL.homeScreen = this;

    return (
      <View style={styles.container}>
        <View style={styles.bg}>
          <ImageBackground
            source={pattern}
            style={styles.img}
            resizeMode="repeat"
            imageStyle={styles.innerImg}
          />
        </View>
        <View style={styles.container}>
          <GlobalSoundButton
            sounds={this.state.allSounds}
            audioOff={this.state.audioOff}
            name="HomeScreenKey"
          ></GlobalSoundButton>
          <Text
            style={[styles.smallText, styles.ppText]}
            onPress={() =>
              Linking.openURL(
                "https://privacy-illuminati-flip.netlify.com"
              ).catch(err => console.error("An error occurred", err))
            }
          >
            Privacy Policy
          </Text>
          <Text style={styles.welcome}>Illuminati Flip</Text>
          <TouchableWithoutFeedback
            onPressIn={evt => this.grabFinger(evt)}
            onPressOut={evt => this.swipe(evt)}
            pressRetentionOffset={{ top: 100, left: 0, bottom: 100, right: 0 }}
          >
            <View style={styles.swipeArea}>
              <View style={styles.gridSelection}>
                <Animated.View
                  pointerEvents={"none"}
                  style={{
                    ...styles.innerGridSelection,
                    transform: [{ translateX: this.springValue }]
                  }}
                >
                  {difficulties}
                </Animated.View>
              </View>
              <View style={styles.margin}>
                <Animated.Image
                  source={swipeFinger}
                  style={{
                    ...styles.hand,
                    transform: [
                      {
                        translateX: this.fingerValue.interpolate({
                          inputRange: [-1, 1],
                          outputRange: [-15, 15]
                        })
                      }
                    ]
                  }}
                />
                <Text style={styles.smallText}>Swipe to change difficulty</Text>
              </View>
            </View>
          </TouchableWithoutFeedback>
          <TouchableOpacity
            activeOpacity={0.8}
            onPress={() => {
              this.checkTutorial();
            }}
          >
            <Text style={styles.button}>Begin Ceremony</Text>
          </TouchableOpacity>
          <Text
            style={[styles.smallText, styles.musicText]}
            onPress={() =>
              Linking.openURL("https://fanlink.to/triobgame").catch(err =>
                console.error("An error occurred", err)
              )
            }
          >
            Music by @triobelisk
          </Text>
          <Text
            style={[styles.smallText, styles.devText]}
            onPress={() =>
              Linking.openURL("https://twitter.com/iamjohnhult").catch(err =>
                console.error("An error occurred", err)
              )
            }
          >
            Developed by @iamjohnhult
          </Text>
        </View>


      </View>
    );
  }
}

const styles = StyleSheet.create({
  ...
});

GlobalState.js如下:

import GLOBAL from "logic/GlobalState.js";

<GlobalSoundButton
   sounds={this.state.allSounds}
   audioOff={GLOBAL.homeScreen.state.audioOff}
   name="GameScreenKey"
></GlobalSoundButton>

0 个答案:

没有答案