Question about the useTodos hook in React Intermediate

Hi Everyone,

In Section 7 “Creating a Custom Query Hook” I am confused about the fetchTodos reference in the useQuery return statement.

I was playing around with the code, and found that adding curly braces around the axios request in fetchTodos will cause the queryKey object property to try and be set as “readonly unknown

So the implementation below is broken, and only renders “undefined”:

const useTodos = () => {
  const fetchTodos = () => {
    axios
      .get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.data);
  };

  return useQuery<Todo[], Error>({
    // No overload matches this call
    // queryKey does not exist in type "readonly unkown[]"
    queryKey: ["todos"],
    queryFn: fetchTodos,
  });
};

But this version works fine:

const useTodos = () => {
  const fetchTodos = () => 
    axios
      .get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.data);

  return useQuery<Todo[], Error>({
    queryKey: ["todos"],
    queryFn: fetchTodos,
  });
};

Embedding the logic directly as the queryFn causes no issues, but abstracting it to this separate function is making it break. Can anyone explain?

I’ve also just found that making fetchTodos an async function that returns the axios Promise will get it working, too:

const useTodos = () => {
  async function fetchTodos() {
    return axios
      .get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.data);
  }

  return useQuery<Todo[], Error>({
    queryKey: ["todos"],
    queryFn: fetchTodos,
  });
};

I’m missing something with the behavior of arrow functions, I think.

Okay: apparently without curly braces the statement is implicitly returned. When you add curly braces, you need to add a return statement

const fetchTodos = () =>
  axios
    .get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
    .then((res) => res.data);

Is effectively the same as

const fetchTodos = async () => {
  return axios
    .get<Todo[]>("https://jsonplaceholder.typicode.com/todos")
    .then((res) => res.data);
}