undefined不是对象(评估'this.props.navigation.navigate)React Native模块

时间:2018-12-21 11:23:07

标签: react-native

我已经安装了react-native-elastic-image-slider模块,并且工作正常。我在模块文件中做了一些自定义更改。它可以工作,但是当我使用this.props.navigation.navigate('View')时,它将显示错误。它在Android设备上正常运行。错误将仅在IOS设备上显示。 模块路径是myapp / node-module / react-native-elastic-image-slider-new 我的模块文件:

import React, {Component} from 'react';
import {
    Image,
    Text,
    View,
    StyleSheet,
    Animated,
    PanResponder,
    TouchableHighlight,
    TouchableOpacity,
    Dimensions,
    LayoutAnimation,
    UIManager,AsyncStorage,
    Platform,ViewPropTypes
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import styles from './style';
import PropTypes from 'prop-types';


class ImageSliderNew extends Component {
    constructor(props) {
        super(props);

        this.state = {
            position: this.props.initialPosition,
            height: new Animated.Value(this._scaleHeight(this.props.images[this.props.initialPosition])),
            left: new Animated.Value(0),
            scrolling: false,
            timeout: null,
            hideArrow:true,
        };

        // Enable LayoutAnimation under Android
        if (Platform.OS === 'android') {
            UIManager.setLayoutAnimationEnabledExperimental(true)
        }
    }

    static defaultProps = {
        position: 0,
        initialPosition: 0
    };

    _move(index) {
        const width = Dimensions.get('window').width;
        const to = index * -width;
        const scaleH = this._scaleHeight(this.props.images[index]);

        Animated.timing(this.state.left, {toValue: to, friction: 10, tension: 10, velocity: 1, duration: 10}).start();
        Animated.timing(this.state.height, {
            toValue: scaleH,
            friction: 10,
            tension: 10,
            velocity: 1,
            duration: 10
        }).start();

        if (this.state.timeout) {
            clearTimeout(this.state.timeout);
        }        
        this.setState({
            position: index,
            timeout: setTimeout(() => {
                this.setState({scrolling: true, timeout: null});
                if (this.props.onPositionChanged) {
                    this.props.onPositionChanged(index);
                }
            }, 10)
        });
    }

    _scaleHeight(image) {
        const imageWidth = Dimensions.get('window').width;
        const imageHeight = Dimensions.get('window').width-35;
        return Dimensions.get('window').width * imageHeight / imageWidth;
    }

    _getPosition() {
        if (typeof this.props.position === 'number') {
            //return this.props.position;
        }
        return this.state.position;
    }

    componentWillReceiveProps(props) {
        if (props.position !== undefined) {
            this.setState({scrolling: true});
            this._move(props.position);
        }
    }

    componentWillMount() {
        const width = Dimensions.get('window').width;
//~ alert('yes'+Math.round(this.props.images.length/2))
        this.state.left.setValue(-(width * this.state.position));        
    if(Math.round(this.props.images.length/2) >1)
    {
        this.setState({hideArrow:true})
        }
    else{
        this.setState({hideArrow:false})
        }   

        if (typeof this.props.position === 'number') {
            //this.state.left.setValue(-(width * this.props.position));
        }

        let release = (e, gestureState) => {
            const width = Dimensions.get('window').width;
            const relativeDistance = gestureState.dx / width;
            const vx = gestureState.vx;
            let change = 0;

            if (relativeDistance < -0.5 || (relativeDistance < 0 && vx <= 0.5)) {
                change = 1;
            } else if (relativeDistance > 0.5 || (relativeDistance > 0 && vx >= 0.5)) {
                change = -1;
            }
            const position = this._getPosition();
            if (position === 0 && change === -1) {
                change = 0;
            } else if (position + change >= Math.round(this.props.images.length/2)) {
                change = (Math.round(this.props.images.length/2)) - (position + change);
            }
            this._move(position + change);
            return true;
        };

        this._panResponder = PanResponder.create({
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => Math.abs(gestureState.dx) > 5,
            onPanResponderRelease: release,
            onPanResponderTerminate: release,
            onPanResponderMove: (e, gestureState) => {
                const dx = gestureState.dx;
                const width = Dimensions.get('window').width;
                const position = this._getPosition();
                let left = -(position * width) + Math.round(dx);
                if (left > 0) {
                    left = Math.sin(left / width) * (width / 2);
                } else if (left < -(width * (Math.round(this.props.images.length/2) - 1))) {
                    const diff = left + (width * (Math.round(this.props.images.length/2) - 1));
                    left = Math.sin(diff / width)  (width / 2) - (width  (Math.round(this.props.images.length/2) - 1));
                }
                this.state.left.setValue(left);
                if (!this.state.scrolling) {
                    this.setState({scrolling: true});
                }

                //scale
                let change = 0;

                if (dx >= 0) {
                    change = -1;
                } else if (dx < 0) {
                    change = 1;
                }
                if (position === 0 && change === -1) {
                    change = 0;
                } else if (position + change >= Math.round(this.props.images.length/2)) {
                    change = (Math.round(this.props.images.length/2)) - (position + change);
                }
                const originH = this._scaleHeight(this.props.images[position]);
                const scaleH = this._scaleHeight(this.props.images[position + change]);
                Animated.timing(this.state.height, {
                    toValue: (scaleH - originH)*Math.abs(dx/width) + originH,
                    friction: 10,
                    tension: 10,
                    velocity: 1,
                    duration: 0
                }).start();
            },
            onShouldBlockNativeResponder: () => true
        });
    }

    componentDidMount() {       

    }

    componentWillUnmount() {
        if (this.state.timeout) {
            clearTimeout(this.state.timeout);
        }
    }

    componentWillUpdate() {
        const CustomLayoutAnimation = {
            duration: 100,
            //create: {
            //    type: LayoutAnimation.Types.linear,
            //    property: LayoutAnimation.Properties.opacity,
            //},
            update: {
                type: LayoutAnimation.Types.linear
            }
        };
        LayoutAnimation.configureNext(CustomLayoutAnimation);
        //LayoutAnimation.linear();
    }
  _next() {
    const Ilength  = Math.round(this.props.images.length/2);    
    const pos = this.state.position === Ilength-1 ? 0 : this.state.position + 1;    
    this._move(pos);
    this.setState({position: pos});
  }

  _prev() {
    const Ilength  = Math.round(this.props.images.length/2);    
    const pos = this.state.position === 0 ? Ilength-1 : this.state.position - 1;
    this._move(pos);
    this.setState({position: pos});
  }
  _test(dataval) {        
    const {navigate} = this.props.navigation;         
      this.props.navigation.navigate('View',{ProId:dataval,isLoading:true});
      }
    render() {
        const customStyles = this.props.style ? this.props.style : {};
        const width = Dimensions.get('window').width;
        const position = this._getPosition();
        return (<View>
            <Animated.View
                style={[styles.container, customStyles, {height: Dimensions.get('window').width/1.4, width: width * Math.round(this.props.images.length/2), backgroundColor:'#fff',transform: [{translateX: this.state.left}]}]}
                {...this._panResponder.panHandlers}>
                {this.props.images.map((image, indexI) => {

                    const imageWidth = Dimensions.get('window').width;
                    const imageHeight = Dimensions.get('window').width-35;
                    const scaleH = Dimensions.get('window').width * imageHeight / imageWidth;
                    let captionComponent= <View>
                        {image.title === undefined ? null : <Text style={{width:Dimensions.get('window').width/2.3,fontWeight: '300', fontSize: 13, color: '#333',textAlign:'center'}}>{image.title}</Text>}
                        {image.caption === undefined ? null : <Text style={{width:Dimensions.get('window').width/2.3,fontWeight: '300', fontSize: 13, color: '#ff0000',textAlign:'center'}}>{image.caption}</Text>}
                        </View>;                                            
                    let imageComponent = <TouchableOpacity onPress={() => this._test(image.id)}  key={indexI}>
                        <View>
                        <Animated.Image                        
                        source={{uri: image.url}}
                        style={{height: Dimensions.get('window').width/2.3, width:Dimensions.get('window').width/2.3,backgroundColor:'#fff',marginLeft:10,marginRight:10}}
                        resizeMode={Image.resizeMode.stretch}
                        />
                        {captionComponent}
                        </View></TouchableOpacity>;
                    if(typeof image.url === 'number') {
                        imageComponent = <View><Animated.Image                           
                         source={image.url}
                        style={{height: Dimensions.get('window').width/2.3, width:Dimensions.get('window').width/2.3,backgroundColor:'#fff',marginLeft:10,marginRight:10}}
                            resizeMode={Image.resizeMode.stretch}
                            />
                        {captionComponent}
                        </View>;                            
                    }
                    if (this.props.onPress) {
                        return (
                            <TouchableOpacity                            
                                onPress={() => {
                                    this.props.onPress({ image, index })
                                }}
                                delayPressIn={100}
                                >
                                {imageComponent}
                                {captionComponent}
                            </TouchableOpacity>
                        );
                    } else {
                        return imageComponent;
                    }
                })}
            </Animated.View>  

                <View style={{width:'7%',left:10,position: 'absolute',top:Dimensions.get('window').width/4.5}}>
                    <TouchableOpacity onPress={() => this._prev()}>
                        <Image source={{uri: 'https://www.furnitureinfashion.net/images-dir-mob/arrow-new-arrival-left.png'}} style={{width:20,height:20}} />
                    </TouchableOpacity> 
                </View>         


                <View style={{width:'7%',right:10,position: 'absolute',top:Dimensions.get('window').width/4.5}}>
                    <TouchableOpacity onPress={() => this._next()}>
                        <Image source={{uri: 'https://www.furnitureinfashion.net/images-dir-mob/arrow-new-arrival-right.png'}} style={{width:20,height:2    import React, {Component} from 'react';
import {
    Image,
    Text,
    View,
    StyleSheet,
    Animated,
    PanResponder,
    TouchableHighlight,
    TouchableOpacity,
    Dimensions,
    LayoutAnimation,
    UIManager,AsyncStorage,
    Platform,ViewPropTypes
} from 'react-native';
import { StackNavigator } from 'react-navigation';
import styles from './style';
import PropTypes from 'prop-types';


class ImageSliderNew extends Component {
    constructor(props) {
        super(props);

        this.state = {
            position: this.props.initialPosition,
            height: new Animated.Value(this._scaleHeight(this.props.images[this.props.initialPosition])),
            left: new Animated.Value(0),
            scrolling: false,
            timeout: null,
            hideArrow:true,
        };

        // Enable LayoutAnimation under Android
        if (Platform.OS === 'android') {
            UIManager.setLayoutAnimationEnabledExperimental(true)
        }
    }

    static defaultProps = {
        position: 0,
        initialPosition: 0
    };


    _move(index) {
        const width = Dimensions.get('window').width;
        const to = index * -width;
        const scaleH = this._scaleHeight(this.props.images[index]);

        Animated.timing(this.state.left, {toValue: to, friction: 10, tension: 10, velocity: 1, duration: 10}).start();
        Animated.timing(this.state.height, {
            toValue: scaleH,
            friction: 10,
            tension: 10,
            velocity: 1,
            duration: 10
        }).start();

        if (this.state.timeout) {
            clearTimeout(this.state.timeout);
        }        
        this.setState({
            position: index,
            timeout: setTimeout(() => {
                this.setState({scrolling: true, timeout: null});
                if (this.props.onPositionChanged) {
                    this.props.onPositionChanged(index);
                }
            }, 10)
        });
    }

    _scaleHeight(image) {
        const imageWidth = Dimensions.get('window').width;
        const imageHeight = Dimensions.get('window').width-35;
        return Dimensions.get('window').width * imageHeight / imageWidth;
    }

    _getPosition() {
        if (typeof this.props.position === 'number') {
            //return this.props.position;
        }
        return this.state.position;
    }

    componentWillReceiveProps(props) {
        if (props.position !== undefined) {
            this.setState({scrolling: true});
            this._move(props.position);
        }
    }

    componentWillMount() {
        const width = Dimensions.get('window').width;
//~ alert('yes'+Math.round(this.props.images.length/2))
        this.state.left.setValue(-(width * this.state.position));        
    if(Math.round(this.props.images.length/2) >1)
    {
        this.setState({hideArrow:true})
        }
    else{
        this.setState({hideArrow:false})
        }   

        if (typeof this.props.position === 'number') {
            //this.state.left.setValue(-(width * this.props.position));
        }

        let release = (e, gestureState) => {
            const width = Dimensions.get('window').width;
            const relativeDistance = gestureState.dx / width;
            const vx = gestureState.vx;
            let change = 0;

            if (relativeDistance < -0.5 || (relativeDistance < 0 && vx <= 0.5)) {
                change = 1;
            } else if (relativeDistance > 0.5 || (relativeDistance > 0 && vx >= 0.5)) {
                change = -1;
            }
            const position = this._getPosition();
            if (position === 0 && change === -1) {
                change = 0;
            } else if (position + change >= Math.round(this.props.images.length/2)) {
                change = (Math.round(this.props.images.length/2)) - (position + change);
            }
            this._move(position + change);
            return true;
        };

        this._panResponder = PanResponder.create({
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => Math.abs(gestureState.dx) > 5,
            onPanResponderRelease: release,
            onPanResponderTerminate: release,
            onPanResponderMove: (e, gestureState) => {
                const dx = gestureState.dx;
                const width = Dimensions.get('window').width;
                const position = this._getPosition();
                let left = -(position * width) + Math.round(dx);
                if (left > 0) {
                    left = Math.sin(left / width) * (width / 2);
                } else if (left < -(width * (Math.round(this.props.images.length/2) - 1))) {
                    const diff = left + (width * (Math.round(this.props.images.length/2) - 1));
                    left = Math.sin(diff / width)  (width / 2) - (width  (Math.round(this.props.images.length/2) - 1));
                }
                this.state.left.setValue(left);
                if (!this.state.scrolling) {
                    this.setState({scrolling: true});
                }

                //scale
                let change = 0;

                if (dx >= 0) {
                    change = -1;
                } else if (dx < 0) {
                    change = 1;
                }
                if (position === 0 && change === -1) {
                    change = 0;
                } else if (position + change >= Math.round(this.props.images.length/2)) {
                    change = (Math.round(this.props.images.length/2)) - (position + change);
                }
                const originH = this._scaleHeight(this.props.images[position]);
                const scaleH = this._scaleHeight(this.props.images[position + change]);
                Animated.timing(this.state.height, {
                    toValue: (scaleH - originH)*Math.abs(dx/width) + originH,
                    friction: 10,
                    tension: 10,
                    velocity: 1,
                    duration: 0
                }).start();
            },
            onShouldBlockNativeResponder: () => true
        });
    }

    componentDidMount() {       

    }

    componentWillUnmount() {
        if (this.state.timeout) {
            clearTimeout(this.state.timeout);
        }
    }

    componentWillUpdate() {
        const CustomLayoutAnimation = {
            duration: 100,
            //create: {
            //    type: LayoutAnimation.Types.linear,
            //    property: LayoutAnimation.Properties.opacity,
            //},
            update: {
                type: LayoutAnimation.Types.linear
            }
        };
        LayoutAnimation.configureNext(CustomLayoutAnimation);
        //LayoutAnimation.linear();
    }
  _next() {
    const Ilength  = Math.round(this.props.images.length/2);    
    const pos = this.state.position === Ilength-1 ? 0 : this.state.position + 1;    
    this._move(pos);
    this.setState({position: pos});
  }

  _prev() {
    const Ilength  = Math.round(this.props.images.length/2);    
    const pos = this.state.position === 0 ? Ilength-1 : this.state.position - 1;
    this._move(pos);
    this.setState({position: pos});
  }
  _test(dataval) {        
    const {navigate} = this.props.navigation;         
      this.props.navigation.navigate('View',{ProId:dataval,isLoading:true});
      }
    render() {
        const customStyles = this.props.style ? this.props.style : {};
        const width = Dimensions.get('window').width;
        const position = this._getPosition();
        return (<View>
            <Animated.View
                style={[styles.container, customStyles, {height: Dimensions.get('window').width/1.4, width: width * Math.round(this.props.images.length/2), backgroundColor:'#fff',transform: [{translateX: this.state.left}]}]}
                {...this._panResponder.panHandlers}>
                {this.props.images.map((image, indexI) => {

                    const imageWidth = Dimensions.get('window').width;
                    const imageHeight = Dimensions.get('window').width-35;
                    const scaleH = Dimensions.get('window').width * imageHeight / imageWidth;
                    let captionComponent= <View>
                        {image.title === undefined ? null : <Text style={{width:Dimensions.get('window').width/2.3,fontWeight: '300', fontSize: 13, color: '#333',textAlign:'center'}}>{image.title}</Text>}
                        {image.caption === undefined ? null : <Text style={{width:Dimensions.get('window').width/2.3,fontWeight: '300', fontSize: 13, color: '#ff0000',textAlign:'center'}}>{image.caption}</Text>}
                        </View>;                                            
                    let imageComponent = <TouchableOpacity onPress={() => this._test(image.id)}  key={indexI}>
                        <View>
                        <Animated.Image                        
                        source={{uri: image.url}}
                        style={{height: Dimensions.get('window').width/2.3, width:Dimensions.get('window').width/2.3,backgroundColor:'#fff',marginLeft:10,marginRight:10}}
                        resizeMode={Image.resizeMode.stretch}
                        />
                        {captionComponent}
                        </View></TouchableOpacity>;
                    if(typeof image.url === 'number') {
                        imageComponent = <View><Animated.Image                           
                         source={image.url}
                        style={{height: Dimensions.get('window').width/2.3, width:Dimensions.get('window').width/2.3,backgroundColor:'#fff',marginLeft:10,marginRight:10}}
                            resizeMode={Image.resizeMode.stretch}
                            />
                        {captionComponent}
                        </View>;                            
                    }
                    if (this.props.onPress) {
                        return (
                            <TouchableOpacity                            
                                onPress={() => {
                                    this.props.onPress({ image, index })
                                }}
                                delayPressIn={100}
                                >
                                {imageComponent}
                                {captionComponent}
                            </TouchableOpacity>
                        );
                    } else {
                        return imageComponent;
                    }
                })}
            </Animated.View>  

                <View style={{width:'7%',left:10,position: 'absolute',top:Dimensions.get('window').width/4.5}}>
                    <TouchableOpacity onPress={() => this._prev()}>
                        <Image source={{uri: 'https://www.furnitureinfashion.net/images-dir-mob/arrow-new-arrival-left.png'}} style={{width:20,height:20}} />
                    </TouchableOpacity> 
                </View>         


                <View style={{width:'7%',right:10,position: 'absolute',top:Dimensions.get('window').width/4.5}}>
                    <TouchableOpacity onPress={() => this._next()}>
                        <Image source={{uri: 'https://www.furnitureinfashion.net/images-dir-mob/arrow-new-arrival-right.png'}} style={{width:20,height:20}} />
                    </TouchableOpacity>               
                </View>

        </View>);
    }
}

ImageSliderNew.propTypes = {
    images: PropTypes.array,
    caption: PropTypes.string,
    title: PropTypes.string,    
    id:PropTypes.number,
    position: PropTypes.number,
    initialPosition: PropTypes.number,
    onPositionChanged: PropTypes.func,
    style: ViewPropTypes.style
};
export default ImageSliderNew;0}} />
                    </TouchableOpacity>               
                </View>

        </View>);
    }
}

ImageSliderNew.propTypes = {
    images: PropTypes.array,
    caption: PropTypes.string,
    title: PropTypes.string,    
    id:PropTypes.number,
    position: PropTypes.number,
    initialPosition: PropTypes.number,
    onPositionChanged: PropTypes.func,
    style: ViewPropTypes.style
};
export default ImageSliderNew;

我该怎么做才能在“查看屏幕”上进行导航?

2 个答案:

答案 0 :(得分:0)

使用此

 _test=(dataval)=> {        
   const {navigate} = this.props.navigation;         
   navigate('View',{ProId:dataval,isLoading:true});
  }

或构造方法中的bind方法

this._test = this._test.bind(this);

答案 1 :(得分:0)

您尝试过吗?

import { NavigationActions } from 'react-navigation';
this.props.dispatch(
       NavigationActions.navigate({
         routeName: 'View',
       })
     )

还是这个?

import { withNavigation } from 'react-navigation'
export default withNavigation(ImageSliderNew)