代码之家  ›  专栏  ›  技术社区  ›  Lucas Leone

调用函数时的钩子调用无效[重复]

  •  0
  • Lucas Leone  · 技术社区  · 1 年前

    我正在做一个React项目。我有两个可重用的函数,它们向API发出请求。当我调用函数时,react会引发错误:

    错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:

    1. React和渲染器(如React DOM)的版本可能不匹配
    2. 你可能违反了胡克规则
    3. 您可能在同一应用程序中有多个React副本

    我已获取Customers.jsx:

    export default function fetchCustomers() {
      const [customers, setCustomers] = useState([]);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await axios.get('customers/', {
              headers: {
                'Authorization': `Bearer ${localStorage.getItem('access_token')}`
              }
            });
            setCustomers(response.data);
          } catch (error) {
            console.error("Error al obtener los datos de clientes.", error);
          }
        };
    
        fetchData();
      }, []);
    
      return customers;
    }
    

    fetchSales.jsx:

    export default function fetchSales(params = {}) {
      const [sales, setSales] = useState([]);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await axios.get('sales/', {
              params: params,
              headers: {
                'Authorization': `Bearer ${localStorage.getItem('access_token')}`
              }
            });
            setSales(response.data.results);
          } catch (error) {
            console.error("Error al obtener los datos de ventas.", error);
          }
        };
    
        fetchData();
      }, []);
    
      return sales;
    }
    

    和cobrar.jsx:

    export default function Cobrar() {
      const [filter, setFilter] = useState({
        startDate: null,
        endDate: null,
        customer: null,
        uncharged: true,
      });
      const [customers, setCustomers] = useState([]);
      const [sales, setSales] = useState([]);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const customersResponse = fetchCustomers();
            setCustomers(customersResponse);
            const salesResponse = fetchSales();
            setSales(salesResponse);
          } catch (error) {
            console.error("Error al obtener los datos.", error);
          }
        }
    
        fetchData();
      }, []);
    

    我试着调用const中的函数,但无法通过params过滤销售额。我想获得所有的销售额,然后按日期范围和一些字段进行筛选。

    1 回复  |  直到 1 年前
        1
  •  3
  •   David    1 年前

    fetchCustomers fetchSales 被写成 钩子 ,而不是其他常规函数。首先,将它们重命名为 useCustomers useSales (与钩子的命名一致)。然后,将它们用作组件中的挂钩:

    export default function Cobrar() {
      const [filter, setFilter] = useState({
        startDate: null,
        endDate: null,
        customer: null,
        uncharged: true,
      });
    
      const customers = useCustomers();
      const sales = useSales();
    
      // the rest of this component...
    

    您不需要重复使用state,因为钩子在内部维护它们的状态。


    或者,如果 不要 希望这些函数是自定义钩子,删除它们对钩子的内部使用,使它们成为直接返回结果的函数。例如

    export default async function fetchCustomers() {
    
      const response = await axios.get('customers/', {
        headers: {
          'Authorization': `Bearer ${localStorage.getItem('access_token')}`
        }
      });
    
      return response.data;
    
    }
    

    然后,您可以在任何上下文中调用该函数,而不需要无效的钩子调用,因为该函数不再尝试使用钩子。


    全面的

    • 不要加倍追踪州内的数据。保持多个数据源同步是一个很难解决的问题,也是一个不必要的问题。跟踪组件中的状态 用钩子钩住,而不是两者都钩住。
    • 钩子只能从组件或其他钩子调用,并且在渲染组件/钩子时必须始终以相同的顺序调用。它们不能在函数等中有条件地调用。