当前位置: 首页 > 知识库问答 >
问题:

React useState钩子在提交表单时不工作

令狐灿
2023-03-14

我是新来的反应,我有一些疑问关于useState钩子。我最近正在开发一个基于应用编程接口的食谱反应应用程序。我面临的问题是,当我在搜索表单中提交东西时,状态应该发生变化,但状态没有变化,但如果我重新提交表单,状态就会发生变化。

   import React,{useState,useEffect} from "react";
   import Form from "./componnents/form";
   import RecipeBlock from "./componnents/recipeblock"
   import './App.css';


   function App() {


     const API_id=process.env.REACT_APP_MY_API_ID;
     const API_key=process.env.REACT_APP_MY_API_KEY;
     const [query,setQuery]=useState("chicken");

    const path=`https://api.edamam.com/search?q=${query}&app_id=${API_id}&app_key=${API_key}`


    const [recipe,setRecipe]=useState([]);

  useEffect(() => {
  console.log("use effect is running")
  getRecipe(query);
  

  }, []);

function search(queryString){

 setQuery(queryString);

 getRecipe();

 }

  async function getRecipe(){
    const response=await fetch(path);
    const data=await response.json();

    setRecipe(data.hits);
    console.log(data.hits);

}

函数的作用是:保存表单输入的值,每次我提交表单时,该值都是正确的,但是setQuery(queryString)不会更改查询值或状态,如果我重新提交表单,它会更改状态。

共有2个答案

东门茂实
2023-03-14

代码中的主要问题是在setQuery(queryString)之后直接运行getRecipe()setQuery(queryString)是异步的,将对状态更改进行排队。然后直接在之后运行getRecipe()时,状态仍将保留query(和path)的旧值,因此无法正确获取新数据。

一种解决方案是在依赖于路径的useffect()中调用getRecipe()

useEffect(() => {
  getRecipe();
}, [path]);

function search(queryString){
  setQuery(queryString);
  // getRecipe() <- removed
}

[path]作为useffect()的依赖项提供时,只要path发生更改,就会自动调用getRecipe()。因此,我们不必从search()手动调用它,因此可以从函数体中删除getRecipe()。这也使得当前的useffect()(没有[path]依赖项)变得多余,因此可以将其删除。

另一种解决方案是通过getRecipe()参数提供新的query值,消除对状态的依赖。

function search(queryString){
  setQuery(queryString);
  getRecipe(queryString);
}

async function getRecipe(query) {
  const path = `https://api.edamam.com/search?q=${query}&app_id=${API_id}&app_key=${API_key}`;
  const response = await fetch(path); // <- is no longer dependent upon the state
  const data = await response.json();
  setRecipe(data.hits);
}

这确实需要在getRecipe()中移动路径定义

印季
2023-03-14

你提供的代码没有意义。

useEffect(() => {
  console.log("use effect is running")
  getRecipe(query);
  

  }, []);

您的getRecipe不接受变量。但据我所知,无论何时搜索,您都希望设置查询,然后从该查询中获取配方。

使用useEffect,您可以在运行函数之前传入参数以检查它们是否更改。因此,更新setQuery,然后当组件重新加载时,如果查询发生更改,它将触发useffect。下面是要解释的代码

  useEffect(() => {
  console.log("use effect is running")
  getRecipe(query);    <-- this doesn't make sense on your code 
  

  }, [query]);

function search(queryString){

 setQuery(queryString);
 }

当状态更新时执行此操作会导致组件重新呈现,因此,如果查询已更改,它将调用getRecipe函数。

 类似资料:
  • 下面是MultistepForm的代码。我已经实现了一个多步骤表单功能,所以这里一切都很好,只是问题是在这个表单中,我在最后一步有一个预览页面,所以当我点击提交按钮时,表单正在消失,按钮正在顶部移动。所以如果有人能帮我请。

  • 我从一个简单的表单提交示例开始 下面是文件 spring-servlet.xml testlink.jsp: 控制器: blank.jsp 我的jsp页面位于 tradelc\src\main\webapp\jsp\testlink.jsp tradelc\src\main\webapp\jsp\blank.jsp 当我给出http://localhost:8181/trade LC/JSP/te

  • 如果我们在提交配置清单之前能够发现其中的语法错误将会是个好消息。 检查 Puppet 配置清单的语法可以使用 puppet parser validate 命令: # puppet parser validate /etc/puppet/manifests/site.pp err: Could not parse for environment production: Syntax error a

  • 我刚开始研究Git钩子,但我似乎无法让它们运行。 注意:这是在Windows7电脑上。

  • 我在一个基于Spring的Web应用程序(版本4.1.6。RELEASE,Spring Security 4.0.0。RELEASE)中工作,我收到错误(POST方法)。根据Spring的留档“Spring Security自动为任何

  • 获取Form变量 通过Action的如下方法可以获取变量: GetSlice GetString GetInt GetBool GetFloat GetFile GetForm 自动映射 通常我们通过http.Request.Form来获得从用户中请求到服务器端的数据,这些数据一般都是采用name,value的形式提交的。xweb默认支持自动将这些变量映射到Action的成员中,并且这种映射支持子