反应本机反应导航的问题

时间:2021-01-22 06:41:27

标签: reactjs react-native react-navigation

好的,所以我一直在玩 React Native 并开始构建一个有趣的应用。

现在我已经实现了 @react-navigation,但是每次我从 A => B 导航时,A 都会被渲染并丢失其所有状态。我不明白为什么会这样。如果有请告诉我。

这是我从 Home 导航到 Detalj 然后 home 失去所有状态的示例。

这是我的应用程序

import React, {useState} from 'react';
import {StyleSheet, ScrollView, View, Text, Route} from 'react-native';
import Home from './components/home';
import Search from './components/search';
import Detali from './components/detali';
import {Picker} from '@react-native-community/picker';

import includedParser from './includedParser';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import {createDrawerNavigator} from '@react-navigation/drawer';
import IParser from './interface/parsers';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import Ionicons from 'react-native-vector-icons/Ionicons';
import lightItem from './cl/lightItem';

const parser = includedParser();
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const App = () => {
  const [value, setValue] = useState(parser[0]);
  const [selectedItem, setSelectedItem] = useState({} as lightItem);

  const buttomContainer = () => {
    return (
      <>
        <View style={styles.header}>
          <Picker
            selectedValue={value.url}
            onValueChange={(v) =>
              setValue(parser.filter((x) => x.url == v)[0])
            }>
            {parser.map((x) => (
              <Picker.Item
                key={x.url}
                label={'Source: ' + x.name}
                value={x.url}
              />
            ))}
          </Picker>
        </View>
        <Tab.Navigator
          tabBarOptions={{
            style: {height: 30},
            showLabel: false,
          }}>
          <Tab.Screen
            name="Home"
            options={{
              // eslint-disable-next-line react/display-name
              tabBarIcon: ({color, size}) => (
                <MaterialCommunityIcons name="home" color={color} size={size} />
              ),
            }}>
            {({navigation}) => (
              <Home
                item={value as IParser}
                itemSelectedCallBack={setSelectedItem}
                navigation={navigation}
              />
            )}
          </Tab.Screen>
          <Tab.Screen
            name="Search"
            options={{
              // eslint-disable-next-line react/display-name
              tabBarIcon: ({color, size}) => (
                <Ionicons name="search" color={color} size={size} />
              ),
            }}>
            {({navigation}) => (
              <Search
                item={value as IParser}
                itemSelectedCallBack={setSelectedItem}
                navigation={navigation}
              />
            )}
          </Tab.Screen>
        </Tab.Navigator>
      </>
    );
  };

  const stackNav = () => {
    return (
      <Stack.Navigator
        screenOptions={{
          headerShown: false,
        }}>
        <Stack.Screen name="Container" component={buttomContainer} />
        <Stack.Screen name="Detali">
          {({navigation}) => (
            <Detali
              parser={value as IParser}
              item={selectedItem}
              navigation={navigation}
            />
          )}
        </Stack.Screen>
      </Stack.Navigator>
    );
  };
  return (
    <>
      <NavigationContainer>{stackNav()}</NavigationContainer>
    </>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 0,
    backgroundColor: '#fff',
    justifyContent: 'center',
  },

  header: {
    backgroundColor: '#6eaaff',
    padding: 5,
  },
});

export default App;

这里是我的家

import React from 'react';
import item from '../cl/lightItem';
import {
  StyleSheet,
  ScrollView,
  View,
  Text,
  Image,
  NativeScrollEvent,
  ActivityIndicator,
  TouchableHighlight,
} from 'react-native';
import parser from '../interface/parsers';
import httpClient from "../cl/http";

export default class Home extends React.Component<{item: parser, itemSelectedCallBack : Function, navigation?: any}, any> {
  state = {data: [],  isLoading: false};
  page =0;
  endResult= false;
  mounted =false;

  filter(items : item[]) : item[]{
    return items.filter(x=> !this.state.data.find((a : item)=> a.title === x.title));
  }
  async getData() {
    this.page++;
    if (this.endResult && this.page>1)
        return;
    this.setState(httpClient.cloneItem(this.state, {isLoading:true}));
    var items = this.page >1 ?this.filter( await this.props.item?.latest(this.page)) :  await this.props.item?.latest(this.page);;
    if (items.length<=0)
       {
         this.endResult = true;
         this.setState(httpClient.cloneItem(this.state, {isLoading:false}));
         return;
       }

    if (this.page >1)
        items = this.state.data.concat(items as []);
    this.setState(httpClient.cloneItem(this.state, {isLoading:false, data: items}));
  }

  componentDidMount() {
    this.getData();
    this.mounted=true;
  }

  isCloseToBottom = (nativeEvent: NativeScrollEvent) => {
    const paddingToBottom = 5;
    return (
      nativeEvent.layoutMeasurement.height + nativeEvent.contentOffset.y >=
      nativeEvent.contentSize.height - paddingToBottom
    );
  };

  componentDidUpdate(prevProps : {item: parser}) {
    if (prevProps.item !== this.props.item) {
      this.page =0;
      this.scroll.scrollTo({y:0});
      this.getData();
    }
  }

  itemClick(item : item) {
    this.props.itemSelectedCallBack(item)
    this.props.navigation.push("Detali")
  }

  render() {
    return (
      <ScrollView ref={(c) => { this.scroll = c; }}
        onScroll={({nativeEvent}) => {
          if (this.isCloseToBottom(nativeEvent)) {
            if (this.props.item.panination && !this.state.isLoading) {
              this.getData();
            }
          }
        }}>
        <View style={styles.container}>
          {this.state.data.map((x: item,index:number) => (
            <TouchableHighlight key={index} onPress={()=> this.itemClick(x)}>
              <View key={x.title} style={styles.product}>
                <Image
                  style={styles.image}
                  source={{uri: x.image}}></Image>
                <View style={styles.footer}>
                  <Text style={{fontSize: 8, overflow:"hidden",textAlign:"center", width:90}}>{x.title}</Text>
                </View>
              </View>
            </TouchableHighlight>
          ))}
          {this.state.isLoading ? <ActivityIndicator size="large" color="#0000ff" /> : null}
        </View>
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 10,
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
    marginBottom:20
  },

  product: {
    width: 100,
    height: 140,
    margin: 2,
    fontSize: 10,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#CCC',
    overflow: 'hidden',
  },
  footer: {
    backgroundColor: '#6eaaff',
    paddingLeft: 5,
    paddingTop:3,
    paddingRight: 5,
    height: 30,
    flex: 0,
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
  },

  image: {
    flex: 0,
    alignSelf: 'stretch', 
    height:"80%",
    width:100,
  }
});

0 个答案:

没有答案