преобразование компонентов класса в функциональные компоненты react native

#javascript #react-native

#javascript #react-native

Вопрос:

поскольку я новичок в react native. я не очень разбираюсь в компонентах класса. я застрял в коде, поскольку в этом коде используются компоненты класса, но я хочу преобразовать их в функциональные компоненты. кто-нибудь, пожалуйста, помогите мне преобразовать данный код в функциональный компонент. это код карты для прокрутки в 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 amp;amp;
                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. вам нужно использовать справочники состояния, такие как useState и useEffect … но, честно говоря, реакция на основе классов намного более управляема и менее похожа на спагетти, как имхо … функциональные компоненты на самом деле ничего не отображают в таблице (вы все еще можете использовать state и useEffect внутри классов, если хотите), из тестов, которые я видел онлайн, классы также быстрее визуализируются

2. В документации React явно упоминается, что вы не можете использовать перехватчики (useState, useEffect и т.д.) В компоненте класса.

Ответ №1:

часть в методе рендеринга — это то, что вы возвращаете.

для создания объектов состояния в функциональных компонентах вам нужно будет использовать 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
  

опять же, есть еще много возможностей для useEffect, если вы хотите что-то делать при обновлении определенного состояния или реквизита