代码之家  ›  专栏  ›  技术社区  ›  Paul

React native Animated undefined不是对象(正在评估“u.stopTracking”)

  •  0
  • Paul  · 技术社区  · 7 年前

    我有以下问题: "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>
        );
      }
    }
    
    0 回复  |  直到 7 年前
        1
  •  2
  •   dugong    7 年前

    我知道你问这个问题已经有一段时间了。我不知道你是如何解决这个问题的,但我也犯了同样的错误:

    "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,
          };
    

    关于动画API的文档太差了,所以我不知道为什么,但这解决了我的问题。

    编辑:

    我设法把它放在了状态下,它没有给出前一个错误。但是,我需要使用以下代码来更改动画值: this.state.marginLeft2.setValue(amount); 这实际上是直接改变状态,而不使用 .setState() .我觉得不太好。

    推荐文章