useEffect 使用异步函数时不更新状态(或在状态更改时不再运行)- Nextjs13

huangapple go评论68阅读模式
英文:

useEffect with asyn function not updating state (or not running again with state change) - Nextjs13

问题

我正在尝试在React中适应异步数据获取,并且有一些我不理解的地方。

我需要从我的API渲染出一份食谱列表,这是我用来获取食谱的路由,它运行正常。这是在获取时调用的:

/api/recipes

现在在我的React组件中,我似乎不明白如何让我的状态更新,或者我的useEffect似乎无法响应获取调用的解析并设置新状态。

我理解设置状态也是异步的,所以我在第一个控制台日志中看不到新状态,但是在依赖数组中有recipes状态更改时,应该在第二次看到它。

所以要么我的useEffect没有正确运行,要么我的状态甚至没有更新。

顺便说一下,如果我console.log(ress.recipes),它会返回我的食谱,数据/端点运行正常

英文:

I'm trying to get used to async data fetching in react and there's something I'm misunderstanding.

I need to render out a list of recipes from my API, this is the route I fetch that gets me my recipes, it works fine. This is called when fetching
/api/recipes

import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";

export async function GET(req){
	const supabase = createRouteHandlerClient({ cookies });
  let recipes, error;
  try {
    ({data : recipes, error} = await supabase.from('Recipes').select('*'));
    if(error){
      throw error;
    }
    console.log(recipes)

  } catch (error) {
    console.log(error)
    alert(error.description || error.message);
  }
  return NextResponse.json({recipes})
}

Now in my react component, I cant seem to understand how to get my state to update or my useeffect doesnt seem to respond to the fetch calls resolving and setting a new state.

"use client"
import { useState, useEffect } from "react";

export default function() {

  const [recipes, setRecipes] = useState([])
  
  useEffect(() => {
    async function getRecipes() {
      const res = await fetch("/api/recipes");
      const ress = await res.json();
      setRecipes[ress.recipes];
    }
    getRecipes();

    console.log(recipes)
  }, [recipes])
  
  

  return (
    <div className="font-sans text-3xl">
      {recipes}
    </div>
  );
}

I understand that setting state is also async so I wont see the new state in the first console log however I should see it on a second time when the recipes state changes as its in my dependency array.

So either my useeffect isnt running right, or my state isnt even updating.

btw if I console.log(ress.recipes) it returns my recipes, the data/endpoint works fine

答案1

得分: 1

以下是翻译好的部分:


这个语法是错误的:

setRecipes[ress.recipes];

你应该使用 括号 来调用函数,而不是 方括号

setRecipes(ress.recipes);

不要在依赖数组中包含 recipes

}, [recipes])

因为每当 recipes 改变时,效果都会重新运行。而由于效果会改变 recipes,这将导致无限循环。可以使用一个空的依赖数组,以便在组件首次渲染时执行效果:

}, [])

移除这行代码:

console.log(recipes)

它不会显示有意义的内容,因为(1)异步操作尚未完成,而且(2)即使等待该操作,状态也尚未更新。


除此之外,你的下一步就是决定如何实际显示这些记录。只显示原始数组不会非常有用:

{recipes}

你可以遍历数组,并为每个记录显示一些标记。例如:

{recipes.map(r => (
  <div>在这里展示来自 "r" 的信息</div>
))}
英文:

A few issues I'm seeing...


This syntax is wrong:

setRecipes[ress.recipes];

You invoke a function with parentheses, not brackets:

setRecipes(ress.recipes);

Don't include recipes in the dependency array:

}, [recipes])

Because every time recipes changes, the effect will re-run. And since the effect changes recipes, that's an infinite loop. Use an empty dependency array to execute the effect just once when the component first renders:

}, [])

Remove this:

console.log(recipes)

It won't show you anything meaningful, since (1) the asynchronous operation hasn't completed yet and (2) even if you await that operation, the state hasn't been updated yet.


Aside from that, your next step will simply be to decide how you want to actually display these records. Just showing the raw array won't be very useful:

{recipes}

You can iterate over the array and show some markup for each record. For example:

{recipes.map(r =&gt; (
  &lt;div&gt;Show information from &quot;r&quot; here.&lt;/div&gt;
))}

huangapple
  • 本文由 发表于 2023年7月13日 21:20:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679832.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定