我遇到以下问题:"undefined is not an object (evaluating 'u.stopTracking')"
。
当在Expo
上更新props
,尝试在componentWillReceiveProps
,stopAnimation()
和stopTracking()
上使用时,会发生这种情况,但是我做不到。
链接博览会:Here
要使错误出现,只需单击中央播放器的图像。
有人可以帮我吗?
应用程式:
import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground } from 'react-native';
import { Constants } from 'expo';
import Album from './Album';
import Track from './Track';
const State = ['normal', 'transparent', 'big'];
export default class App extends React.Component {
constructor() {
super();
this.state = {
type: 0,
};
}
render() {
let { type } = this.state;
return (
<View style={styles.container}>
<ImageBackground
source={{
uri:
'https://i.pinimg.com/originals/62/6f/84/626f84c40696c1308a77fd8331e12b3e.jpg',
}}
imageStyle={{ borderRadius: 4 }}
style={{
alignItems: 'center',
justifyContent: 'center',
height: 400,
width: 400,
}}>
<Album
type={State[type]} //normal,transparent,big
title={Track.name}
artist={Track.artists[0].name}
cover={Track.album.images[0].url}
onPress={() => {
type = ++type % 3;
this.setState({ type });
}}
/>
</ImageBackground>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#fff',
},
});
专辑:
import * as React from 'react';
import {
Text,
View,
StyleSheet,
ImageBackground,
Animated,
TouchableOpacity,
} from 'react-native';
const size = 40;
export default class Album extends React.Component {
constructor(props) {
super(props);
this.min = size / 4;
this.max = size / 2;
this.heightCenter = new Animated.Value(this.min);
this.heightLateral = new Animated.Value(size / 2);
/*this.state = {
heightCenter: new Animated.Value(this.min),
heightLateral: new Animated.Value(size / 2),
};*/
}
animateBar = (el, value) => {
var newValue = value == this.max ? this.min : this.max;
Animated.timing(el, {
toValue: value,
}).start(() => this.animateBar(el, newValue));
};
onPress = e => {
return this.props.onPress(e);
};
componentDidMount() {
console.log(this.heightCenter)
this.animateBar(this.heightCenter, this.min);
this.animateBar(this.heightLateral, this.max);
}
componentWillReceiveProps(nextProps) {
if (nextProps.type !== this.props.type) {
console.log('componentWillReceiveProps');
//this.state.heightCenter.stopAnimation();
//this.state.heightLateral.stopAnimation();
//Animated.stopTracking();
//Animated.timing(this.heightCenter).stopTracking();
//Animated.timing(this.heightLateral).stopTracking();
/*this.state.heightCenter.stopTracking();
this.state.heightLateral.stopTracking();
this.state.heightCenter.stopAnimation();
this.state.heightLateral.stopAnimation();*/
//this.heightCenter = {};
//this.heightLateral = null;
//this.heightCenter.stopTracking();
//this.heightLateral.stopTracking();
//this.state.heightCenter.stopAnimation();
//this.state.heightLateral.stopAnimation();
console.log(this.heightCenter)
}
}
componentDidUnmount() {
console.log('componentDidUnmount');
//Animated.timing(this.heightCenter).stop();
//Animated.timing(this.heightLateral).stop();
}
componentDidUpdate() {
this.animateBar();
}
render() {
let { type, title, artist, cover } = this.props;
let barWidthCenter = {
height: this.heightCenter,
};
let barWidthLateral = {
height: this.heightLateral,
};
if (type != 'normal' && type != 'transparent' && type != 'big')
type = 'transparent';
let backgroundColor =
type == 'normal' ? 'rgba(255,255,255,1)' : 'rgba(255,255,255,0.5)';
let color = type == 'normal' ? '#000' : '#fff';
if (type == 'big')
return (
<TouchableOpacity onPress={() => this.onPress()}>
<View
style={{
alignItems: 'center',
justifyContent: 'center',
}}>
<ImageBackground
source={{
uri: cover,
}}
imageStyle={{ borderRadius: 4 }}
style={{
flexDirection: 'row',
alignItems: 'flex-end',
justifyContent: 'flex-start',
height: 200,
width: 200,
}}>
<View
style={{
borderRadius: 4,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0.3)',
padding: 5,
height: 40,
width: 40,
margin: 5,
}}>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthLateral,
]}
/>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthCenter,
]}
/>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthLateral,
]}
/>
</View>
</ImageBackground>
<View style={{ paddingLeft: 12, paddingRight: 12 }}>
<Text style={{ fontWeight: 'bold', color: '#fff' }}>{title}</Text>
<Text style={{ color: '#fff' }}>{artist}</Text>
</View>
</View>
</TouchableOpacity>
);
return (
<TouchableOpacity onPress={() => this.onPress()}>
<View
style={{
backgroundColor: backgroundColor,
flexDirection: 'row',
justifyContent: 'center',
borderRadius: 4,
padding: 4,
}}>
<ImageBackground
source={{
uri: cover,
}}
imageStyle={{ borderRadius: 4 }}
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
height: size,
width: size,
}}>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthLateral,
]}
/>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthCenter,
]}
/>
<Animated.View
style={[
{
backgroundColor: 'rgba(255,255,255,1)',
width: 5,
borderRadius: 5 / 2,
margin: 2,
},
barWidthLateral,
]}
/>
</ImageBackground>
<View style={{ paddingLeft: 12, paddingRight: 12 }}>
<Text style={{ fontWeight: 'bold', color }}>{title}</Text>
<Text style={{ color }}>{artist}</Text>
</View>
</View>
</TouchableOpacity>
);
}
}
最佳答案
我看已经有一段时间你问了这个问题。我不知道您是如何解决此问题的,但是我遇到了相同的错误:"undefined is not an object (evaluating 'u.stopTracking')"
由于这里的代码:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
elementPositionX: 0,
target: null,
marginLeft: new Animated.Value(0),
};
之所以发生这种情况,是因为我将动画值置于状态中。它应该已经将状态定义为组件类的属性,如下所示:
export default class App extends React.Component {
constructor(props) {
super(props);
this.marginLeft= new Animated.Value(0);
this.state = {
elementPositionX: 0,
target: null,
};
关于Animated API的文档太少了,所以我不确定为什么,但是这解决了我的问题。
编辑:
我设法以某种方式将其置于状态,并且在不给出先前错误的情况下仍能正常工作。但是,我需要使用以下代码来更改动画值:
this.state.marginLeft2.setValue(amount);
,这实际上是在直接更改状态-不使用.setState()
。对我来说似乎不好。