React 查询 useQuery() 和 useState()

问题描述 投票:0回答:1

我在 React Native 应用程序中有一个屏幕,我在其中使用

useQuery
获取一些数据,使用
setState
将此数据保存在对象状态中,然后更新子组件内的状态值。获取数据后我陷入状态初始化。使用现已弃用的
onSuccess
钩子可能会容易得多,但我想知道是否有更好的替代方案。

我正在使用

React 18
React Native 0.72
React Query v5

我尝试了以下方法:

  1. useQuery 的
    select
    属性:
const {refetch, data, isLoading, error} = useQuery({
    queryKey: ['leadPreferences'],
    queryFn: async () => getLeadPreferences(setLoggedIn),
    select: (res) => {
      if (res != null) {
        const leadPreferencesData = res.body;
        console.log('running this: ', i++);
        return updateLeadPreferences({
          destinations: [],
          whatsAppContact: leadPreferencesData.whatsapp_contact,
          whatsAppCommStatus: leadPreferencesData.whatsapp_enabled,
          leadEmail: leadPreferencesData.alert_email_ids,
          emailAlertStatus: leadPreferencesData.email_alert_enabled,
          emailAlertTimes: [],
          leadTypes: leadPreferencesData.lead_types,
          packageTypes: leadPreferencesData.package_types,
          defaultHomePage: leadPreferencesData.landing_page,
        });
      }
    },
  });

这会引发

data is undefined
错误。

2. useQuery 调用之前和之后的

useEffect
方法:

useEffect(() => {
    if (data && data != undefined) {
      const leadPreferencesData = data.body;
      console.log('running this: ', i++);
      updateLeadPreferences({
        destinations: [],
        whatsAppContact: leadPreferencesData.whatsapp_contact,
        whatsAppCommStatus: leadPreferencesData.whatsapp_enabled,
        leadEmail: leadPreferencesData.alert_email_ids,
        emailAlertStatus: leadPreferencesData.email_alert_enabled,
        emailAlertTimes: [],
        leadTypes: leadPreferencesData.lead_types,
        packageTypes: leadPreferencesData.package_types,
        defaultHomePage: leadPreferencesData.landing_page,
      });
    }
  },);

应该发生什么:

每当

data
的值发生变化时,状态都必须更新。 问题: 抛出“无法读取未定义的属性” -> 如果在 useQuery 挂钩之前调用 useEffect “比之前的渲染期间渲染了更多的钩子” -> 如果在 useQuery 之后调用 useEffect,并使用
data
作为依赖数组。

  1. 在 UI 返回之前调用
    updateLeadPreferences
    。 在调试器抛出“太多重新渲染”错误之前,这会导致大约 51 次渲染。
react-native react-hooks tanstackreact-query
1个回答
0
投票

你能尝试一次然后告诉我吗? (如下)

使用 useQuery 获取数据,而无需尝试直接在选择函数中设置状态。选择选项应该纯粹用于选择或转换要在组件中使用的数据,而不是用于更新状态等副作用。利用 useEffect 来观察 useQuery 返回的数据的变化,然后相应地更新组件的状态。

//small example in line with your code
import React, { useState, useEffect } from 'react';
import { useQuery } from 'react-query';

const initialLeadPreferencesState = {
  destinations: [],
  whatsAppContact: '',
  whatsAppCommStatus: false,
  leadEmail: '',
  emailAlertStatus: false,
  emailAlertTimes: [],
  leadTypes: [],
  packageTypes: [],
  defaultHomePage: '',
};

const YourComponent = () => {
  const [leadPreferences, setLeadPreferences] = useState(initialLeadPreferencesState);

  const { data, isLoading, error } = useQuery('leadPreferences', async () => {
    const response = await getLeadPreferences();
    return response.body;
  });

  useEffect(() => {
    if (data) {
      const leadPreferencesData = data;
      setLeadPreferences({
        ...leadPreferences,
        whatsAppContact: leadPreferencesData.whatsapp_contact,
        whatsAppCommStatus: leadPreferencesData.whatsapp_enabled,
        leadEmail: leadPreferencesData.alert_email_ids,
        emailAlertStatus: leadPreferencesData.email_alert_enabled,
        leadTypes: leadPreferencesData.lead_types,
        packageTypes: leadPreferencesData.package_types,
        defaultHomePage: leadPreferencesData.landing_page,
      });
    }
  }, [data]); // Dependency array ensures this effect runs only when `data` changes

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>An error occurred</div>;

  return (
    <div>
      {/* Render your UI here using `leadPreferences` state */}
    </div>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.