问题
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>
);
}
};
回答1:
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!
来源:https://stackoverflow.com/questions/62804518/react-native-this-setstate-is-not-a-function-trying-to-animate-background-co