美文网首页
react-navigation-hook如何优雅的实现Refo

react-navigation-hook如何优雅的实现Refo

作者: 西西的一天 | 来源:发表于2019-10-12 12:51 被阅读0次

项目基于React Native 0.60+,完全使用React Hooks。

前言

首先介绍一下想要解决的问题,当离开某页面再次回来时触发一个事件,离开的方式包括switch tab 和 navigate.

使用useFocusState存在的问题

首先想到的应该就是使用useFocusState来解决问题(在新的release中已经将这个API定义为弃用了,也有相应的取代API)。使用方式如下所示:

export const HomeScreen = () => {
    const {navigate} = useNavigation();
    const focusState = useFocusState();
    console.log(focusState);
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text onPress={() => {
                navigate("Detail")
            }}>Home Screen</Text>
        </View>
    );
};

当该Screen是渲染的首页面时,这个focusState将发生多次变更,如下图所示。想要实现需求需要添加额外的Flag,极大的降低了代码的可读性。

focusState状态变更

使用useFocusEffect存在的问题

这个API最近期release的,它的表现就稳定了很多,使用方法如下:

export const HomeScreen = () => {
    const {navigate} = useNavigation();
    useFocusEffect(() => {
        console.log("focus");
    });
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text onPress={() => {
                navigate("Detail")
            }}>Home Screen</Text>
        </View>
    );
};

使用这个effect,当首次渲染,以及从其他页面回到该页面时都会触发callback。看一下需求,离开该页面,再次回到该页面时,触发一个事件。当然是要在加一个useState,判断是否为首次加载,即可解决。问题又来了,应该在什么时刻来更改这个state呢?当加入flag,可读性和可维护性都将降低。

如何通过自定义Hook来解决

自己动手,丰衣足食。手动撸一段代码,我们需要的是状态变更时触发,要记录状态,自然想到了useReducer,通过监听isBlurred的变更,触发事件,dispatchreducerreducer根据本次状态和上次状态判读是否调用callback。代码如下所示:

interface State {
    disappeared: boolean;
}
interface Action {
    type: string;
    payload: {
        disappeared: boolean;
    };
}
export const useRefocusEffect = (onRefocus: () => void): void => {
    const reducer = (previousState: State, action: Action): State => {
        if (action.type === "refresh") {
            if (previousState.disappeared && !action.payload.disappeared) {
                onRefocus();
            }
            return { disappeared: action.payload.disappeared };
        }
        return { ...previousState };
    };
    const { isBlurred } = useFocusState();
    const [ , dispatch ] = useReducer(reducer, { disappeared: isBlurred });
    useEffect(() => {
        dispatch({ type: "refresh", payload: { disappeared: isBlurred } });
    }, [ isBlurred ]);
};

使用方法也很简单:

export const HomeScreen = () => {
    const {navigate} = useNavigation();
    useRefocusEffect(() => {
        console.log("refocus");
    });
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text onPress={() => {
                navigate("Detail")
            }}>Home Screen</Text>
        </View>
    );
};

完整实例代码也已上传:demo

相关文章

  • react-navigation-hook如何优雅的实现Refo

    项目基于React Native 0.60+,完全使用React Hooks。 前言 首先介绍一下想要解决的问题,...

  • WebStorm

    WebStorm入门指南 WebStorm webstorm是如何格式化代码 , 双击shift , 搜索refo...

  • 优雅的调用RESTful API

    代码量越少越优雅,实现越简单越优雅,下面介绍如何优雅的实现API调用。 1 单资源访问 下面以华为云IoT平台提供...

  • WKWebView POST请求

    这一文章介绍如何通过类目让WKWebView优雅的实现POST请求,为啥说是优雅: 实现POST请求 实现原理是通...

  • Master Your Mind Counterintuitiv

    下载地址:Master Your Mind Counterintuitive Strategies to Refo...

  • 一些js小技巧

    1、如何优雅的取随机字符窜 2、如何使用位运算符优雅的取整 3、如何用正则优雅的实现金钱格式化 4、如何最佳让两个...

  • 简短优雅地利用js实现 sleep 函数

    简短优雅地实现 sleep 函数 很多语言都有 sleep 函数,显然 js 没有,那么如何能简短优雅地实现这个方...

  • js 骚操作

    1、如何优雅的取随机字符串 2、如何优雅的取整 3、优雅的金钱格式化 4、两个属性换值 5、实现深拷贝

  • 022-谈谈 reactiveCocoa

    一句话:链式编程,论如何优雅的实现MVVM。

  • 如何优雅的实现ThreadLocal

    大部分翻译自How is ThreadLocal implemented?对代码作了更新这是一个关于跳脱固有框架思...

网友评论

      本文标题:react-navigation-hook如何优雅的实现Refo

      本文链接:https://www.haomeiwen.com/subject/ocrqmctx.html