React Native TabBar Навигация при медленном переходе для переходов при вызове Actions.componentName () из response-native-router-flux - PullRequest
0 голосов
/ 04 марта 2020

Настройки среды: Запуск USB на устройстве Samsung S6 android. Убунту 18.04. Chrome Отладка отключена.

"dependencies": {
    "@react-native-community/masked-view": "^0.1.6",
    "d3": "^5.15.0",
    "jetifier": "^1.6.5",
    "moment": "^2.24.0",
    "react": "^16.12.0",
    "react-native": "0.61.5",
    "react-native-gesture-handler": "^1.6.0",
    "react-native-gifted-chat": "^0.13.0",
    "react-native-reanimated": "^1.7.0",
    "react-native-rename": "^2.4.1",
    "react-native-router-flux": "^4.2.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.0.0",
    "react-native-shadow": "^1.2.2",
    "react-native-svg": "^11.0.1",
    "react-native-vector-icons": "^6.6.0",
    "react-with-direction": "^1.3.1"
  },

TabBar еще не готов к работе, но пробовал без функции действий от router-flux, и это довольно быстро. примерно в 2 или 3 раза быстрее, чем когда вызывается действие. Это традиционный компонент. Может быть, вызов render может вызвать рендеринг с каждой вкладки всего, что пульсирует при нажатии? Я попытался изменить if if в actionExecute () внутри StaticTabbar. js, но ничего не изменилось с точки зрения производительности. Я также хотел бы отметить, что весь этот контент имеет статус c и не вызывается ни один сетевой запрос, и я не использую expo.

StaticTabbar. js Компонент

import * as React from "react";
import {
    View,
    Text,
    Animated,
    Dimensions,
    StyleSheet,
    TouchableWithoutFeedback
} from "react-native";
import { Actions } from "react-native-router-flux";
import Icon from 'react-native-vector-icons/Feather';

const { width } = Dimensions.get("window");

export default class StaticTabbar extends React.PureComponent {

    constructor(props) {
        super(props);
        const { tabs } = this.props;
        this.values = tabs.map((tab, index) => new Animated.Value(index === 0 ? 1 : 0));
    };

    onPress = index => {
        const { value, tabs } = this.props;
        const tabWidth = width / tabs.length;

        Animated.sequence([
            Animated.parallel(
                this.values.map(v => Animated.timing(v, {
                    toValue: 0,
                    duration: 100,
                    useNativeDriver: true,
                })),
            ),
            Animated.parallel([
                Animated.spring(value, {
                    toValue: tabWidth * index,
                    useNativeDriver: true,
                }),
                Animated.spring(this.values[index], {
                    toValue: 1,
                    useNativeDriver: true,
                }),
            ]),
        ]).start();

    }

    render() {
        const { onPress } = this;
        const { tabs, value } = this.props;

        return (
            <View style={styles.container}>
            {
                tabs.map((tab, key) => {
                    const actionExecute = () => {
                        if (tab.name === "Chats") {return Actions.chats()}
                        else if (tab.name === "Recents"){ return Actions.recents()}
                        else {return Actions.call()}
                    }
                    const tabWidth = width / tabs.length;
                    const cursor = tabWidth * key;
                    const opacity = value.interpolate({
                        inputRange: [cursor - tabWidth, cursor, cursor + tabWidth],
                        outputRange: [1, 0, 1],
                        extrapolate: "clamp",
                    });
                    const translateY = this.values[key].interpolate({
                        inputRange: [0, 1],
                        outputRange: [64, 0],
                        extrapolate: "clamp",
                    });
                    const opacity1 = this.values[key].interpolate({
                        inputRange: [0, 1],
                        outputRange: [0, 1],
                        extrapolate: "clamp",
                    });
                    return (
                        <React.Fragment {...{ key }}>
                            <TouchableWithoutFeedback onPress={() => {  onPress(key);actionExecute()}}>
                                <Animated.View style={[styles.tab, { opacity }]}>
                                    <Icon name={tab.icon} size={18} style={{paddingRight:5}} color="#D8D1F3"/>           
                                    <Text style={{color: "rgba(255, 255, 255, 0.6)",fontSize: 15, fontFamily: "CerebriSans-Book"}}>
                                        {tab.name}
                                    </Text>
                                </Animated.View>
                            </TouchableWithoutFeedback>
                            <Animated.View style={{ position: "absolute", top: -8, left: tabWidth * key, width: tabWidth, height: 64, justifyContent: "center", alignItems: "center", opacity: opacity1, transform: [{ translateY }] }}>
                                <View style={styles.activeIcon}>
                                    <Icon name={tab.icon} size={18} style={{paddingRight:5}} color="#3611BA"/>           
                                    <Text 
                                        style={{
                                        color: "#3611BA",
                                        fontSize: 15,
                                        fontFamily: "CerebriSans-Bold",
                                        }}
                                    >{tab.name}</Text>
                                </View>
                            </Animated.View>
                        </React.Fragment>
                    );
                })
            }
            </View>
        );
    };
}

const styles = StyleSheet.create({
    container: {
        flexDirection: "row",
    },
    tab: {
        flexDirection: "row",
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        height: 60,
    },
    activeIcon: {
        flexDirection: "row",
        flex: 1,
        backgroundColor: "transparent",
        alignSelf: 'stretch',
        height: 40,
        justifyContent: "center",
        alignItems: "center",
    },
});

Tabbar . js

import * as React from "react";
import {
  SafeAreaView, StyleSheet, Dimensions, View, Animated,
} from "react-native";
import * as shape from "d3-shape";
import Svg, {
  Path
} from 'react-native-svg';
import StaticTabbar from "./StaticTabbar";

const AnimatedSvg = Animated.createAnimatedComponent(Svg);
const { width } = Dimensions.get("window");
const height = 60;
const tabs = [
  {
    name: "Chats",
    icon: "message-circle"
  },
  {
    name: "Recents",
    icon: "arrow-down-left"
  },
  {
    name: "Call",
    icon: "phone-call"
  },
];

const tabWidth = width / tabs.length;
const backgroundColor = "#360FC0"; 

const getPath = () => {
  const left = shape.line().x(d => d.x).y(d => d.y)([
    { x: 0, y: 0 },
    { x: width, y: 0 },
  ]);
  const tab = shape.line().x(d => d.x).y(d => d.y).curve(shape.curveBasis)([
    { x: width, y: 0 },
    { x: width + 5, y: 0 },
    { x: width + 10, y: 10 }, 
    { x: width + 15, y: height },
    { x: width + tabWidth - 15, y: height },
    { x: width + tabWidth - 10, y: 10 },
    { x: width + tabWidth - 5, y: 0 },
    { x: width + tabWidth, y: 0 },
  ]);
  const right = shape.line().x(d => d.x).y(d => d.y)([
    { x: width + tabWidth, y: 0 },
    { x: width * 2, y: 0 },
    { x: width * 2, y: height },
    { x: 0, y: height },
    { x: 0, y: 0 },
  ]);
  return `${left} ${tab} ${right}`;
};
const d = getPath();

// eslint-disable-next-line react/prefer-stateless-function
export default class Tabbar extends React.PureComponent {
  value = new Animated.Value(0);

  render() {
    const { value } = this;
    const translateX = value.interpolate({
      inputRange: [0, width],
      outputRange: [-width, 0],
    });
    return (
      <>
        <View {...{ height, width }}>
          <AnimatedSvg width={width * 2} {...{ height }} style={{ transform: [{ translateX }] }}>
            <Path fill={backgroundColor} {...{ d }} />
          </AnimatedSvg>
          <View style={StyleSheet.absoluteFill}>
            <StaticTabbar {...{ tabs, value }} />
          </View>
        </View>
        <SafeAreaView style={styles.container} />
      </>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor,
  },
});
...