【问题标题】:SetState with data from React-query with React/Typescript使用 React/Typescript 的 React-query 数据的 SetState
【发布时间】: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/…

标签: javascript reactjs typescript react-query


【解决方案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。
  • 谢谢保罗,我已经用上一个答案工作了,虽然两者都非常相似 - 如果可以的话,我会标记两者
  • 不客气!
猜你喜欢
  • 2021-12-27
  • 2018-12-26
  • 2021-04-21
  • 2018-11-15
  • 1970-01-01
  • 1970-01-01
  • 2019-08-29
  • 2020-07-02
  • 1970-01-01
相关资源
最近更新 更多