将类组件转换为功能组件进行本地响应

时间:2020-09-05 04:53:06

标签: javascript react-native

因为我是本机反应的新手。我对班级成分不了解。我被困在代码中,因为在此代码中使用了类组件,但我想将它们转换为功能组件。任何人都可以帮助我将给定的代码转换为功能组件。这是可滑动刷卡的代码,用于在本机类组件中使用所有给定代码,并对构造函数的使用进行响应。我只想将其转换为功能组件。

    //This is an example of Tinder like Swipeable Card//
    import React, { Component } from 'react';
    //import react in our code.
    import {
    Platform, StyleSheet, View, Text,
    Dimensions, Animated, PanResponder,
    } from 'react-native';
    //import all the components we are going to use.
    const SCREEN_WIDTH = Dimensions.get('window').width;
    class SwipeableCard extends React.Component {
    constructor() {
    super();
    this.panResponder;
    this.state = {
        Xposition: new Animated.Value(0),
        RightText: false,
        LeftText: false,
    };
    this.Card_Opacity = new Animated.Value(1);

    this.panResponder = PanResponder.create({
        onStartShouldSetPanResponder: (evt, gestureState) => false,
        onMoveShouldSetPanResponder: (evt, gestureState) => true,
        onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
        onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
        onPanResponderMove: (evt, gestureState) => {
            this.state.Xposition.setValue(gestureState.dx);
            if (gestureState.dx > SCREEN_WIDTH - 250) {
                this.setState({
                    RightText: true,
                    LeftText: false,
                });
            } else if (gestureState.dx < -SCREEN_WIDTH + 250) {
                this.setState({
                    LeftText: true,
                    RightText: false,
                });
            }
        },
        onPanResponderRelease: (evt, gestureState) => {
            if (
                gestureState.dx < SCREEN_WIDTH - 150 &&
                gestureState.dx > -SCREEN_WIDTH + 150
            ) {
                this.setState({
                    LeftText: false,
                    RightText: false,
                });
                Animated.spring(
                    this.state.Xposition,
                    {
                        toValue: 0,
                        speed: 5,
                        bounciness: 10,
                    },
                    { useNativeDriver: true }
                ).start();
            } else if (gestureState.dx > SCREEN_WIDTH - 150) {
                Animated.parallel(
                    [
                        Animated.timing(this.state.Xposition, {
                            toValue: SCREEN_WIDTH,
                            duration: 200,
                        }),
                        Animated.timing(this.Card_Opacity, {
                            toValue: 0,
                            duration: 200,
                        }),
                    ],
                    { useNativeDriver: true }
                ).start(() => {
                    this.setState({ LeftText: false, RightText: false }, () => {
                        this.props.removeCard();
                    });
                });
            } else if (gestureState.dx < -SCREEN_WIDTH + 150) {
                Animated.parallel(
                    [
                        Animated.timing(this.state.Xposition, {
                            toValue: -SCREEN_WIDTH,
                            duration: 200,
                        }),
                        Animated.timing(this.Card_Opacity, {
                            toValue: 0,
                            duration: 200,
                        }),
                    ],
                    { useNativeDriver: true }
                ).start(() => {
                    this.setState({ LeftText: false, RightText: false }, () => {
                        this.props.removeCard();
                    });
                });
            }
        },
    });
}
render() {
    const rotateCard = this.state.Xposition.interpolate({
        inputRange: [-200, 0, 200],
        outputRange: ['-20deg', '0deg', '20deg'],
    });
    return (
        <Animated.View
            {...this.panResponder.panHandlers}
            style={[
                styles.card_Style,
                {
                    backgroundColor: this.props.item.backgroundColor,
                    opacity: this.Card_Opacity,
                    transform: [
                        { translateX: this.state.Xposition },
                        { rotate: rotateCard },
                    ],
                },
            ]}>
            <Text style={styles.Card_Title}> {this.props.item.card_Title} </Text>
            {this.state.LeftText ? (
                <Text style={styles.Left_Text_Style}> Left Swipe </Text>
            ) : null}
            {this.state.RightText ? (
                <Text style={styles.Right_Text_Style}> Right Swipe </Text>
            ) : null}
        </Animated.View>
         );
     }
   }

    export default class App extends React.Component {
    constructor() {
    super();
    this.state = {
        Sample_Card_Array: [{
            id: '1', card_Title: 'Card 1', backgroundColor: '#FFC107',
        }, {
            id: '2', card_Title: 'Card 2', backgroundColor: '#ED2525',
        }, {
            id: '3', card_Title: 'Card 3', backgroundColor: '#E7088E',
        }, {
            id: '4', card_Title: 'Card 4', backgroundColor: '#00BCD4',
        }, {
            id: '5', card_Title: 'Card 5', backgroundColor: '#FFFB14',
        }],
        No_More_Card: false,
    };
}
componentDidMount() {
    this.setState({
        Sample_Card_Array: this.state.Sample_Card_Array.reverse(),
    });
    if (this.state.Sample_Card_Array.length == 0) {
        this.setState({ No_More_Card: true });
    }
}
removeCard = id => {
    this.state.Sample_Card_Array.splice(
        this.state.Sample_Card_Array.findIndex(x => x.id == id),
        1
    );
    this.setState({ Sample_Card_Array: this.state.Sample_Card_Array }, () => {
        if (this.state.Sample_Card_Array.length == 0) {
            this.setState({ No_More_Card: true });
        }
    });
};
render() {
    return (
        <View style={styles.MainContainer}>
            {this.state.Sample_Card_Array.map((item, key) => (
                <SwipeableCard
                    key={key}
                    item={item}
                    removeCard={this.removeCard.bind(this, item.id)}
                />
            ))}
            {this.state.No_More_Card ? (
                <Text style={{ fontSize: 22, color: '#000' }}>No Cards Found.</Text>
            ) : null}
        </View>
      );
     }
    }
    const styles = StyleSheet.create({
    MainContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    paddingTop: Platform.OS === 'ios' ? 20 : 0,
    },
    card_Style: {
    width: '75%',
    height: '45%',
    justifyContent: 'center',
    alignItems: 'center',
    position: 'absolute',
    borderRadius: 7,
    },
    Card_Title: {
    color: '#fff',
    fontSize: 24,
    },
    Left_Text_Style: {
    top: 22,
    right: 32,
    position: 'absolute',
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold',
    backgroundColor: 'transparent',
    },
    Right_Text_Style: {
    top: 22,
    left: 32,
    position: 'absolute',
    color: '#fff',
    fontSize: 20,
    fontWeight: 'bold',
    backgroundColor: 'transparent',
    },
    });

1 个答案:

答案 0 :(得分:0)

render方法的部分就是返回的内容。

要在功能组件中创建stateObjects,您将需要使用useState方法

const functionalComponent = (props)=>{//props are passed in via props arg...
    const defaultState = Xposition: new Animated.Value(0),
        RightText: false,
        LeftText: false
    }
    const [state,setState] = useState(defaultState);
    ... // more stuff
    return (
        <Animated.View
            {...this.panResponder.panHandlers}
            style={[
                styles.card_Style,
                {
                    backgroundColor: props.item.backgroundColor,
                    opacity: Card_Opacity,
                    transform: [
                        { translateX: state.Xposition },
                        { rotate: rotateCard },
                    ],
                },
            ]}>
            <Text style={styles.Card_Title}> {props.item.card_Title} </Text>
            {this.state.LeftText ? (
                <Text style={styles.Left_Text_Style}> Left Swipe </Text>
            ) : null}
            {this.state.RightText ? (
                <Text style={styles.Right_Text_Style}> Right Swipe </Text>
            ) : null}
        </Animated.View>
         );
}

您应该真正去看useState上的一些视频,您可以更加细化

要设置状态,您将需要使用setState调用返回的useState方法:setState({..state,{XPosition:55})或其他方法……您执行...state来包含旧状态值,因为状态变量将被您传入的内容完全覆盖...它将不会“更新”现有状态,而是将其覆盖

接下来的内容是componentDidMount的功能,您可以使用useEffect

useEffect(()=>{ // this is setup
    // do the stuff from componentDidMount
    return ()=>{ 
       // any required teardown can be done here
    },[] //[] signifies only do this when component mounts... not every update 
);// end useEffect componentDidMount

如果要在更新特定状态或道具时做一些事,再次有很多可以使用的效果