【问题标题】:How to save items with AsyncStorage in one screen and then display it in a different screen如何使用 AsyncStorage 将项目保存在一个屏幕中,然后将其显示在不同的屏幕中
【发布时间】:2021-09-08 19:34:32
【问题描述】:

第一个屏幕显示从第二个屏幕保存项目的历史记录。

第二个屏幕是二维码扫描仪。扫描 QR CODE 后,它会显示一个 Modal,其中包含从 QR CODE 获得的信息。它还有一个按钮来保存信息。保存的信息在第一个屏幕中检索到 FlatList。

我遇到的问题是保存的信息没有显示在第一个屏幕中。 我只在 console.log [Error: [AsyncStorage] Passing null/undefined as value is not supported. If you want to remove value, Use .remove method instead. Passed value: undefined Passed key: @QR

中得到这个

编辑:我忘了写 AsyncStorage Key 是在文件顶部导出的,因此可以在第一个屏幕中导入。

代码:我保存信息的第二个屏幕。

const [Link, setLink] = useState([]);

const onSuccess = e => {
    setModalVisible(true);
    console.log(e);
    const QRSave = setLink(e);
    storeQRCode(QRSave);
  };

const storeQRCode = QRSave => {
    const stringifiedQR = JSON.stringify(QRSave);

    AsyncStorage.setItem(asyncStorage, stringifiedQR).catch(err => {
      console.log(err);
    });
  };

<Button
   title="Save QR"
   onPress={() => {
   scanner.reactivate();
   storeQRCode();
   showToast();
 }}
/>

代码:显示已保存信息历史记录的第一个屏幕。

const [Data, setData] = useState({});

  useEffect(() => {
    restoreQRCode();
  }, []);

  const restoreQRCode = () => {
    AsyncStorage.getItem(asyncStorage)
      .then(stringifiedQR => {
        const parsedQR = JSON.parse(stringifiedQR);
        console.log(stringifiedQR);
        if (!parsedQR || typeof parsedQR !== 'object') return;

        setData(parsedQR);
      })
      .catch(err => {
        console.log(err);
      });
  };

<FlatList
  data={Data}
  keyExtractor={(_, index) => index.toString()}
  renderItem={renderItem}
 />

【问题讨论】:

  • 你使用 react-navigation v5 吗?
  • @NaldDev 是的,我正在使用 React Navigation V5。如果上面的这个选项是不可能的。我必须通过 React Navigation 传递保存的信息。有点想避免这种情况,因为当你只去那个特定的屏幕时,它只能通过 React Navigation 发送数据??????

标签: javascript reactjs react-redux react-native-android asyncstorage


【解决方案1】:

我有替代解决方案,无需将保存的信息传递到上一个屏幕

有焦点监听导航事件,代码是这样的

useEffect(() => {
  const unsubscribe = navigation.addListener('focus', () => {
    // do something when this screen back to focus for example you can load data again whenever that screen focus...

    console.log('Screen X is focus again')
    loadData()
  })

  return unsubscribe
}, [navigation])

您可以在link 中阅读有关此导航事件的更多信息

【讨论】:

  • 嗯不知道该怎么办。我以前没有使用过反应导航事件。有时间我可以研究一下。
  • 我搞定了,它正在显示保存的项目。我遇到了一个问题,那就是。它只显示一项。如果我保存另一个项目。它会替换当前保存的项目,并且不会将第二个项目添加到列表中。
【解决方案2】:

您想要的是围绕两个屏幕的上下文提供程序,然后您可以访问两个屏幕中的数据。

类似:

//QrCodeContext.js
export const QrCodeContext = createContext();

const KEY = "QR";
export const QrCodeProvider = ({ children }) => {
    const [loading, setLoading] = useState(true);
    const [qrCode, setQrCode] = useState({});

    //This effect hook runs on mount and loads your QR code, if it exists.
    useEffect(() => {
        const loadQrCode = async () => {
            const code = await loadItemFromAsyncStorage(KEY, {});
            setQrCode(() => code);
            setLoading(() => false);
        };
        loadQrCode();

    }, [])

    //This effect hook runs every time the code changes and persists it to async storage
    useEffect(() => {
        const storeQrCode = async (value) => {
            await storeItemInAsyncStorage(KEY, value);
        }

        storeQrCode(qrCode);

        return () => {
            storeQrCode(qrCode);
        } // this means the code will always be saved when the component unmounts.

    }, [qrCode]);

    //These three properties are available to your child components.
    const propertiesExposedToConsumers = { setQrCode, qrCode, loading };

    return (<QrCodeContext.Provider value={propertiesExposedToConsumers}>
        {children}
    </QrCodeContext.Provider>
    );
}



//asyncStrageWrapper.js.

export const storeItemInAsyncStorage = async (key, value) => {
    try {
        const jsonValue = JSON.stringify(value);
        await AsyncStorage.setItem(key, jsonValue);
    } catch (e) {
        console.log(e);
    }
};

export const loadItemFromAsyncStorage = async (key, defaultValue = undefined) => {
    try {
        const jsonValue = await AsyncStorage.getItem(key);
        return jsonValue != null ? JSON.parse(jsonValue) : defaultValue;
    } catch (e) {
        console.log(e);
        return defaultValue;
    }
};


//screenOne.js

const ScreenOne = () => {
    const { loading, qrCode } = useContext(QrCodeContext);

   //your render code here
}

//screenTwo.js
const ScreenTwo = () => {
    const { loading, setQrCode } = useContext(QrCodeContext);
    //your scanner code here.
}

//App.js
const App = () => (
    <QrCodeProvider>
       <NavigationContainer>
      <Stack.Navigator initialRouteName={"ScreenOne"}>
      <Stack.Screen name="ScreenOne" component={ScreenOne} />
        <Stack.Screen name="ScreenTwo" component={ScreenTwo} />
      </Stack.Navigator>
    </NavigationContainer>
    </QrCodeProvider >
)

【讨论】:

  • 我现在真的没有时间研究这个。但我会给你赏金,因为它明天到期
猜你喜欢
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多