简体   繁体   English

关于焦点事件的无限循环

[英]about endless loop of focus event

Usually, I would use loading modal to wrap part of getting data, like below.通常,我会使用加载模式来包装获取数据的一部分,如下所示。

showLoading('loading...');
// TODO:  fetch data, eg: axios.get(....)
hiddenLoading();

The loading modal is a screen in react-navigation. so I maked three screen, first screen is list, second screen is edit screen, third screen is loading modal.加载模态是react-navigation中的一个屏幕。所以我制作了三个屏幕,第一个屏幕是列表,第二个屏幕是编辑屏幕,第三个屏幕是加载模态。

      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="list" component={ListScreen}  />
          <Stack.Screen name="edit" component={EditScreen}  />

          <Stack.Group screenOptions={{
            headerShown: false,
            presentation: 'transparentModal',
            contentStyle: {
              backgroundColor: 'rgba(0,0,0, 0.5)',
              justifyContent: 'center',
              alignItems: 'center'
            }
          }}>
            <Stack.Screen name='loading' component={Loading} />
          </Stack.Group>

        </Stack.Navigator>
      </NavigationContainer>

I would click button in list to edit item.我会单击列表中的按钮来编辑项目。 when back come List screen from the edit screen.当从编辑屏幕返回列表屏幕时。 I want refresh list data.我想要刷新列表数据。

So, I would call init to loading data in focus function, but entered loading screen before fetch data.因此,我会调用 init 加载焦点 function 中的数据,但在获取数据之前进入加载屏幕。 when data load finish then go back List screen, the focus event has triggered again.当数据加载完成然后 go 返回列表屏幕时,焦点事件再次触发。


const ListScreen = ()=>{
...
 const init = async () => {
    navigation.navigate('loading');
    const result = await axios.get('http://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
    console.log('respones =>', result);
    navigation.goBack();
  };

  useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      init();   // here has been trigger again, from List screen come back.
    });

    init();
    return unsubscribe;
  }, [navigation]);
...
}

I wish screen can be refresh when come back from loading screen.我希望从加载屏幕回来时可以刷新屏幕。

Rather than creating a new screen for displaying loading indicator you just simply overlay a view to show loading indicator.您无需创建用于显示加载指示器的新屏幕,只需简单地覆盖一个视图即可显示加载指示器。

Here is a example code of a loader component这是加载程序组件的示例代码

import PropTypes from "prop-types";
import React from "react";
import { ActivityIndicator, Text, View, StyleSheet } from "react-native";
import {
  LOADER_ACTIVITY_INDICATOR_SIZE,
  DEFAULT_LOADER_TEXT,TEXT_TYPE
} from "@resources/Constants";
function Loader(props) {
  let { loading, text } = props;
  let { overlayStyle, textStyle } = styles;
  return (
    <>
      {loading ? (
        <View style={overlayStyle}>
          <ActivityIndicator
            size={LOADER_ACTIVITY_INDICATOR_SIZE}
            color={"#4062E2"}
          />
          <Text style={textStyle} type={TEXT_TYPE.TINY}>{text}</Text>
        </View>
      ) : null}
    </>
  );
}

Loader.propTypes = {
  loading: PropTypes.bool,
  text: PropTypes.string,
  theme: PropTypes.object
};

Loader.defaultProps = {
  text: DEFAULT_LOADER_TEXT,
  loading: false
};

const styles = StyleSheet.create({
  overlayStyle: {
    backgroundColor: "rgba(229, 229, 229, 0.8)",
    justifyContent: "center",
    alignItems: "center",
    height: "100 %",
    width: "100%",
    position: "absolute",
    elevation: 1,
    zIndex: 10
  },
  textStyle: {
    fontSize: 18,
    fontWeight: "bold",
    marginTop: 20,
    color: "#707070"
  }
});


export default Loader;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM