为了账号安全,请及时绑定邮箱和手机立即绑定

在 React 中使用自定义钩子获取多个表中的数据时,自定义 ContextProvider

在 React 中使用自定义钩子获取多个表中的数据时,自定义 ContextProvider

慕莱坞森 2023-08-18 17:38:26
我有多个小表,当应用程序更新相应的表时,我希望能够写入/读取/更新我的组件(我们暂时可以认为它是一个单用户应用程序)。我受到这个问题的启发,在我的应用程序中编写了一个自定义提供程序和关联的用于数据获取(并最终发布)的钩子:React useReducer async data fetch我想出了这个:import React from "react";import { useContext, useState, useEffect } from "react";import axios from "axios";const MetadataContext = React.createContext();function MetadataContextProvider(props) {  let [metadata, setMetadata] = useState({});  async function loadMetadata(url) {    let response = await axios.get(url);    // here when I console.log the value of metadata I get {} all the time    setMetadata({ ...metadata, [url]: response.data });  }  async function postNewItem(url, payload) {    await axios.post(url, payload);    let response = await axios.get(url);    setMetadata({ ...metadata, [url]: response.data });  }  return (    <MetadataContext.Provider value={{ metadata, loadMetadata, postNewItem }}>      {props.children}    </MetadataContext.Provider>  );}function useMetadataTable(url) {  // this hook's goal is to allow loading data in the context provider  // when required by some component  const context = useContext(MetadataContext);  useEffect(() => {    context.loadMetadata(url);  }, []);  return [    context.metadata[url],    () => context.loadMetadata(url),    (payload) => context.postNewItem(url, payload),  ];}function TestComponent({ url }) {  const [metadata, loadMetadata, postNewItem] = useMetadataTable(url);  // not using loadMetadata and postNewItem here  return (    <>      <p> {JSON.stringify(metadata)} </p>    </>  );}(代码应该在 CRA 上下文中运行,两个 API 都可以替换为几乎任何 API)当我运行它时,会在两个端点(/api/capteur 和 /api/observation)上触发请求,但我期望 MetadataContextProvider 中的元数据对象有 2 个键:&ldquo;/api/capteur&rdquo;和&ldquo;/ api/observation&rdquo;,只显示最后一次请求的内容。当我在 loadMetadata 函数中 console.log 元数据时,元数据始终具有初始状态挂钩值,即 {}。我对 React 还很陌生,我努力尝试过,但我真的不明白这里发生了什么。有人可以帮忙吗?
查看完整描述

1 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

您的问题是如何使用 更新metadata对象setMetadatametadata在您的上下文中通过更新对象的操作loadMetadata分别由两个“实例”完成:TestComponent#1 和TestComponent#2。它们都可以访问metadata上下文中的对象,但它们不会立即同步,因为useState的 setter 函数是异步工作的。

解决您的问题的简单方法称为功能更新。 useState的 setter 还提供了一个回调函数,它将使用(我在这里过于简单化)“最新”状态。

在您的上下文提供者中:

async function loadMetadata(url) {

  let response = await axios.get(url);

  setMetadata((existingData) => ({ ...existingData, [url]: response.data }));

  // instead of

  // setMetadata({ ...metadata, [url]: response.data });

}

查看完整回答
反对 回复 2023-08-18
  • 1 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信