【问题标题】:convert class components to functional components react native将类组件转换为功能组件 react native
【发布时间】:2020-09-05 13:13:11
【问题描述】:

因为我是 React Native 的新手。我对类组件知之甚少。我被困在代码中,因为此代码中使用了类组件,但我想将它们转换为功能组件。任何人都请帮我把这个给定的代码转换成功能组件。这是一个可刷卡的代码,用于反应原生类组件中的所有给定代码以及构造函数和 this 的使用。我只想将其转换为功能组件。

    //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',
    },
    });

【问题讨论】:

  • 您需要使用像useStateuseEffect 这样的stateHooks ...但老实说,基于类的反应更易于管理,不像恕我直言...功能组件并没有真正带来任何东西表(如果你愿意,你仍然可以在类中使用状态和使用效果),从我在网上看到的基准来看,类的渲染速度也更快
  • React 文档明确提到你不能在类组件中使用钩子(useState、useEffect 等)。

标签: javascript react-native


【解决方案1】:

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 的视频,你可以更细化

要设置状态,您需要使用从useState 调用返回的setState 方法: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 还有很多

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-22
    • 2021-05-29
    • 1970-01-01
    • 2021-06-13
    • 2020-06-23
    • 2020-10-27
    • 2021-10-21
    相关资源
    最近更新 更多