0

I am trying to set the state using setState and it needs to default to the data from React-query, but on refresh it says 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);

then I map over the state object like:

{fetchData.map() etc} 
6
  • „Why do you need to do that“ would be my counter question? Every background refetch from react-query will overwrite the local state with the useEffect solutions, so why not just use the data from useQuery directly? I see no reason to sync state like that… Commented Oct 19, 2021 at 17:16
  • I have filter buttons which I am filtering the array by updating the state and showing the results Commented Oct 19, 2021 at 17:31
  • So my counter question would be, how would I do that without using state? Commented Oct 19, 2021 at 17:32
  • for example, you can store the filter criteria (that the user selects) only and then perform the filtering in the render function. If it's expensive, you can apply useMemo. But storing derived state is rarely the solution because you create two sources of truth. Commented Oct 19, 2021 at 20:10
  • a "filtered list" is even one of the examples in the react-docs for something that is NOT state: reactjs.org/docs/… Commented Oct 19, 2021 at 20:11

2 Answers 2

2

I have set up a working example in the sandbox, you need to set the state data in useEffect and to wrap your app with QueryClientProvider to use userQuery successfully "just to mention that"

Sandbox link

// Alert component

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>
  );
}

// App component

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>
  );
}

Sign up to request clarification or add additional context in comments.

1 Comment

Are you not supposed to pass a query in the array for useEffect?
1

Something like this should work. See codesandbox here for working example.

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>;
}

4 Comments

For the setFetchedData(result) I am getting 'Expected 0 arguments, but got 1.'
have you got this line, or something else? const [fetchedData, setFetchedData] = React.useState([]); if you are using setState it should be expecting an arg.
Thanks Paul, I have got it working with the previous answer, although both very similar - I would mark both if I could
you're welcome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.