反应本机-"this.setState不是函数";尝试设置背景颜色的动画? [英] React native - "this.setState is not a function" trying to animate background color?

查看:59
本文介绍了反应本机-"this.setState不是函数";尝试设置背景颜色的动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我只是想循环播放视图的背景颜色,在3-4种颜色之间逐渐消失.我发现如何对ScrollView的backgroundColor进行动画处理在React Native中并复制了逐字记录,但是从零食的角度来看,我认为这个答案已经过时了.

出现以下错误:

this.setState不是函数

export default props => {
  let [fontsLoaded] = useFonts({
    'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12',
        'SequelSans-RomanDisp' : require('./assets/fonts/SequelSans-RomanDisp.ttf'),
        'SequelSans-BoldDisp' : require('./assets/fonts/SequelSans-BoldDisp.ttf'),
        'SequelSans-BlackDisp' : require('./assets/fonts/SequelSans-BlackDisp.ttf'),
  });
  if (!fontsLoaded) {
    return <AppLoading />;
  } else {

      //Set states
      this.state = {
        backgroundColor: new Animated.Value(0)
      };
      this.setState({ backgroundColor: new Animated.Value(0) }, () => {
       Animated.timing(this.state.backgroundColor, {
        toValue: 100,
        duration: 5000
      }).start();
    });

        var color = this.state.colorValue.interpolate({
            inputRange: [0, 300],
            outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
        });

    const styles = StyleSheet.create({
      container: { flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: this.state.backgroundColor.interpolate({
                inputRange: [0, 100],
                outputRange: ["#00aaFF", "#808080"]
              })
    },

然后我在这里引用此样式:

return (
        <Animated.View style={styles.container}>
          <View style={styles.textWrapper}>
            <Text style={styles.myText}>Login</Text>
          </View>
        </Animated.View>
      );

我在做什么错了?

更新:-与上次渲染相比,渲染了更多的钩子

    export default props => {
  let [fontsLoaded] = useFonts({
    'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12',
        'SequelSans-RomanDisp' : require('./assets/fonts/SequelSans-RomanDisp.ttf'),
        'SequelSans-BoldDisp' : require('./assets/fonts/SequelSans-BoldDisp.ttf'),
        'SequelSans-BlackDisp' : require('./assets/fonts/SequelSans-BlackDisp.ttf'),
  });
  if (!fontsLoaded) {
    return <AppLoading />;
  } else {

    //Set states
      const [backgroundColor, setBackgroundColor] = useState(new Animated.Value(0));

      useEffect(() => {
        setBackgroundColor(new Animated.Value(0));
      }, []);    // this will be only called on initial mounting of component,
      // so you can change this as your requirement maybe move this in a function which will be called,
      // you can't directly call setState/useState in render otherwise it will go in a infinite loop.
      useEffect(() => {
        Animated.timing(this.state.backgroundColor, {
          toValue: 100,
          duration: 5000
        }).start();
      }, [backgroundColor]);

      var color = this.state.colorValue.interpolate({
        inputRange: [0, 300],
        outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
      });

    const styles = StyleSheet.create({
      container: { flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: color
    },
      textWrapper: {
        height: hp('70%'), // 70% of height device screen
        width: wp('80%'),   // 80% of width device screen
        backgroundColor: '#fff',
        justifyContent: 'center',
        alignItems: 'center',
      },
      myText: {
        fontSize: hp('2%'), // End result looks like the provided UI mockup
        fontFamily: 'SequelSans-BoldDisp'
      }
    });

      return (
        <Animated.View style={styles.container}>
          <View style={styles.textWrapper}>
            <Text style={styles.myText}>Login</Text>
          </View>
        </Animated.View>
      );
  }
};

解决方案

您不能在功能组件内部使用它.您犯的唯一错误是,您尝试使用功能组件内的 this.setState 设置状态,而不是使用对功能组件执行相同功能的 useState 钩子.

只需使用 useState useEffect 钩子更改setState功能,如下所示:-

//Set states
const [backgroundColor, setBackgroundColor] = useState(new Animated.Value(0));
const [colorValue, setColorValue] = useState(new Animated.Value(0)); 

useEffect(() => {
  setBackgroundColor(new Animated.Value(0));
}, []);    // this will be only called on initial mounting of component, 
// so you can change this as your requirement maybe move this in a function which will be called, 
// you can't directly call setState/useState in render otherwise it will go in a infinite loop.
useEffect(() => {
  Animated.timing(backgroundColor, {
    toValue: 100,
    duration: 5000
  }).start();
}, [backgroundColor]);

var color = colorValue.interpolate({
  inputRange: [0, 300],
  outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
});

这是使用 useState和useEffect 钩子在类组件中完成操作的方法!

Alright Im just trying to loop the background color of a view, fading between 3-4 colors. I found How to animate the backgroundColor of a ScrollView in React Native and have copied verbatim, but looking at the Snack, I believe this answer is out of date.

With the following, I get the error:

this.setState is not a function

export default props => {
  let [fontsLoaded] = useFonts({
    'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12',
        'SequelSans-RomanDisp' : require('./assets/fonts/SequelSans-RomanDisp.ttf'),
        'SequelSans-BoldDisp' : require('./assets/fonts/SequelSans-BoldDisp.ttf'),
        'SequelSans-BlackDisp' : require('./assets/fonts/SequelSans-BlackDisp.ttf'),
  });
  if (!fontsLoaded) {
    return <AppLoading />;
  } else {

      //Set states
      this.state = {
        backgroundColor: new Animated.Value(0)
      };
      this.setState({ backgroundColor: new Animated.Value(0) }, () => {
       Animated.timing(this.state.backgroundColor, {
        toValue: 100,
        duration: 5000
      }).start();
    });

        var color = this.state.colorValue.interpolate({
            inputRange: [0, 300],
            outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
        });

    const styles = StyleSheet.create({
      container: { flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: this.state.backgroundColor.interpolate({
                inputRange: [0, 100],
                outputRange: ["#00aaFF", "#808080"]
              })
    },

Then I reference this style here:

return (
        <Animated.View style={styles.container}>
          <View style={styles.textWrapper}>
            <Text style={styles.myText}>Login</Text>
          </View>
        </Animated.View>
      );

What am I doing wrong here?

UPDATE: - Rendered more hooks than during the previous render

    export default props => {
  let [fontsLoaded] = useFonts({
    'Inter-SemiBoldItalic': 'https://rsms.me/inter/font-files/Inter-SemiBoldItalic.otf?v=3.12',
        'SequelSans-RomanDisp' : require('./assets/fonts/SequelSans-RomanDisp.ttf'),
        'SequelSans-BoldDisp' : require('./assets/fonts/SequelSans-BoldDisp.ttf'),
        'SequelSans-BlackDisp' : require('./assets/fonts/SequelSans-BlackDisp.ttf'),
  });
  if (!fontsLoaded) {
    return <AppLoading />;
  } else {

    //Set states
      const [backgroundColor, setBackgroundColor] = useState(new Animated.Value(0));

      useEffect(() => {
        setBackgroundColor(new Animated.Value(0));
      }, []);    // this will be only called on initial mounting of component,
      // so you can change this as your requirement maybe move this in a function which will be called,
      // you can't directly call setState/useState in render otherwise it will go in a infinite loop.
      useEffect(() => {
        Animated.timing(this.state.backgroundColor, {
          toValue: 100,
          duration: 5000
        }).start();
      }, [backgroundColor]);

      var color = this.state.colorValue.interpolate({
        inputRange: [0, 300],
        outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
      });

    const styles = StyleSheet.create({
      container: { flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: color
    },
      textWrapper: {
        height: hp('70%'), // 70% of height device screen
        width: wp('80%'),   // 80% of width device screen
        backgroundColor: '#fff',
        justifyContent: 'center',
        alignItems: 'center',
      },
      myText: {
        fontSize: hp('2%'), // End result looks like the provided UI mockup
        fontFamily: 'SequelSans-BoldDisp'
      }
    });

      return (
        <Animated.View style={styles.container}>
          <View style={styles.textWrapper}>
            <Text style={styles.myText}>Login</Text>
          </View>
        </Animated.View>
      );
  }
};

解决方案

You can not use this inside a functional component. The only mistake you made is you are trying to set state using this.setState inside a functional component instead of using useState hook which does the same work for functional component.

Just change your setState functionality using useState and useEffect hook as below:-

//Set states
const [backgroundColor, setBackgroundColor] = useState(new Animated.Value(0));
const [colorValue, setColorValue] = useState(new Animated.Value(0)); 

useEffect(() => {
  setBackgroundColor(new Animated.Value(0));
}, []);    // this will be only called on initial mounting of component, 
// so you can change this as your requirement maybe move this in a function which will be called, 
// you can't directly call setState/useState in render otherwise it will go in a infinite loop.
useEffect(() => {
  Animated.timing(backgroundColor, {
    toValue: 100,
    duration: 5000
  }).start();
}, [backgroundColor]);

var color = colorValue.interpolate({
  inputRange: [0, 300],
  outputRange: ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)']
});

This is how it could be done in a class component using useState and useEffect hooks, Enjoy!

这篇关于反应本机-"this.setState不是函数";尝试设置背景颜色的动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆