使用 React/Typescript 的 React-query 数据的 SetState

Posted

技术标签:

【中文标题】使用 React/Typescript 的 React-query 数据的 SetState【英文标题】:SetState with data from React-query with React/Typescript 【发布时间】:2021-12-06 14:22:57 【问题描述】:

我正在尝试使用 setState 设置状态,它需要默认为来自 React-query 的数据,但刷新时显示 undefined

const fetchAlerts = async () => 
    const res = await fetch('https://jsonplaceholder.typicode.com/todos');
    return res.json();
;

 const  data, status  = useQuery('todos', fetchTodos, 
    staleTime: 5000,
);

const result = data;

const [fetchData, setFetchData] = React.useState<ITodo[]>(result);

然后我像这样映射状态对象:

fetchData.map() etc 

【问题讨论】:

“你为什么需要这样做”是我的反问? react-query 的每次后台重新获取都会使用 useEffect 解决方案覆盖本地状态,那么为什么不直接使用 useQuery 中的数据呢?我认为没有理由像那样同步状态…… 我有过滤按钮,我通过更新状态和显示结果来过滤数组 所以我的反问是,如果不使用状态,我将如何做到这一点? 例如,您可以只存储过滤条件(用户选择的),然后在渲染函数中执行过滤。如果贵,可以申请useMemo。但是存储派生状态很少是解决方案,因为您创建了两个事实来源。 “过滤列表”甚至是 react-docs 中的示例之一,用于表示非状态:reactjs.org/docs/… 【参考方案1】:

我在沙箱中设置了一个工作示例,您需要在useEffect 中设置状态数据并使用QueryClientProvider 包装您的应用程序以成功使用userQuery“只是提一下”

Sandbox link

// 警报组件

import React,  useEffect  from "react";
import  useQuery  from "react-query";
import "./styles.css";

interface ITodo 
  userId: string;
  id: string;
  title: string;


const fetchAlerts = async () => 
  const res = await fetch("https://jsonplaceholder.typicode.com/todos");
  return res.json();
;

export default function Component() 
  const [fetchData, setFetchData] = React.useState<ITodo[]>([]);

  const  data, status  = useQuery<ITodo[]>("mytodos", fetchAlerts, 
    staleTime: 5000
  );

  useEffect(() => 
    setFetchData(data ?? []);
  , [data]);

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      fetchData.map((x) => (
        <li>
          " "
          x.userId - x.id - x.title.substr(10)
        </li>
      ))
    </div>
  );


// 应用组件

import "./styles.css";
import Component from "./component";
import  QueryClient, QueryClientProvider  from "react-query";
export default function App() 
  const queryClient = new QueryClient();
  return (
    <QueryClientProvider client=queryClient>
      <div className="App">
        <Component />
      </div>
    </QueryClientProvider>
  );


【讨论】:

难道你不应该在数组中传递一个查询以获得 useEffect 吗?【参考方案2】:

这样的事情应该可以工作。有关工作示例,请参见codesandbox。

function Example() 
  const [fetchedData, setFetchedData] = React.useState([]);

  const fetchTodos = async () => 
    const res = await fetch("https://jsonplaceholder.typicode.com/todos");
    return res.json();
  ;

  const  data: result  = useQuery("todos", fetchTodos, 
    staleTime: 5000
  );

  React.useEffect(() => 
    setFetchedData(result);
  , [result]);

  return <p>JSON.stringify(fetchedData)</p>;

【讨论】:

对于 setFetchedData(result) ,我得到“预期 0 个参数,但得到 1 个。” 你有这条线,还是别的什么? const [fetchedData, setFetchedData] = React.useState([]); 如果您使用的是 setState,它应该期待一个 arg。 谢谢保罗,我已经用上一个答案工作了,虽然两者都非常相似 - 如果可以的话,我会标记两者 不客气!

以上是关于使用 React/Typescript 的 React-query 数据的 SetState的主要内容,如果未能解决你的问题,请参考以下文章

使用react搭建组件库:react+typescript

React 和 TypeScript:避免使用上下文默认值

如何使用 React + Typescript 嵌入 YouTube iframe?

入门TypeScript编写React

React + Typescript:TypeScript 错误:类型“字符串”与类型“CSSProperties”没有共同的属性

你如何在带有 Typescript 的 create-react-app 中使用 Mocha?