【问题标题】:Custom React Native Asyncstorage hook causes weird results?自定义 React Native Asyncstorage 钩子会导致奇怪的结果?
【发布时间】:2022-01-12 08:43:56
【问题描述】:

我在 React Native 中有一个项目,它利用 React Navigation 和 Asyncstorage 来存储要由子屏幕编辑的数据。由于我们需要在全局范围内监听每个键的变化,我制作了以下利用 EventEmitter 的 Asyncstorage 钩子:

import AsyncStorage from "@react-native-async-storage/async-storage";
import EventEmitter from "eventemitter3";
import { useEffect, useState } from "react";

const eventEmitter = new EventEmitter();

/**
 * Acts as a react hook for AsyncStorage
 * @param id - ID of the element
 * @param defaultValue - Default value of the element
 * @returns A react hook of the element
 */
export default function useStorage<Type>(id: string, defaultValue: Type): [Type, (value: Type) => Promise<void>] {
    const [version, setVersion] = useState(0);
    const [data, setData] = useState(defaultValue);

    // Grab Data
    const getData = async () => {
        const jsonData = await AsyncStorage.getItem(id);
        if (jsonData)
            setData(JSON.parse(jsonData) as Type);
    };
    useEffect(() => { getData(); }, [version]);

    // Save Data
    const saveData = async (value: Type) => {
        const jsonData = JSON.stringify(value);
        await AsyncStorage.setItem(id, jsonData);
        setData(value);
        eventEmitter.emit(id);
    }
    useEffect(() => {
        let isMounted = true;

        const handleDataChange = () => {
            if (isMounted) {
                setVersion(v => v + 1);
            }
        }
        const unmount = () => {
            isMounted = false;
            eventEmitter.removeListener(id, handleDataChange);
        }

        eventEmitter.addListener(id, handleDataChange);
        return unmount;
    }, [id]);

    return [data, saveData];
}

但是,每当我使用它时,我都会得到非常奇怪的结果,包括...

  • 当同一个键同时在父屏幕和子屏幕上时,数据无法正确加载
  • 数据未正确更新
  • 挂钩未正确清理

我错过了什么吗?是什么导致了所有这些问题?有没有更好的实现方式?

注意:我知道 React Redux 存在,但我希望尽可能避免它。

【问题讨论】:

    标签: reactjs react-native react-hooks react-navigation asyncstorage


    【解决方案1】:

    在单个函数中调用多个setStates() 可能会导致意外的副作用。通过将代码调整为每个函数仅使用 1 个setState(),可以避免这些问题。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 2010-11-14
    • 2018-01-24
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    相关资源
    最近更新 更多