【问题标题】:React useState hook is not working when submitting form提交表单时React useState钩子不起作用
【发布时间】:2021-03-10 12:48:45
【问题描述】:

我是 React 新手,我对 useState hook 有一些疑问。我最近正在开发一个基于 API 的配方反应应用程序。我面临的问题是,当我在搜索表单中提交某些内容时,应该会发生状态更改,但是状态没有改变,但如果我重新提交表单,状态就会改变。

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

}

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

【问题讨论】:

    标签: javascript reactjs react-hooks use-state


    【解决方案1】:

    您提供的代码没有意义。

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

    您的 getRecipe 没有变量。但据我了解,每当您搜索时,您都想设置查询,然后从该查询中获取配方。

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

      useEffect(() => {
      console.log("use effect is running")
      getRecipe(query);    <-- this doesn't make sense on your code 
      
    
      }, [query]);
    
    function search(queryString){
    
     setQuery(queryString);
     }
    

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

    【讨论】:

    • 谢谢。我忘了更新我的 getRecipe() 函数
    • 如果您可以投票并接受将不胜感激的答案,请不要担心
    【解决方案2】:

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

    一种解决方案是在依赖于pathuseEffect() 中调用getRecipe()

    useEffect(() => {
      getRecipe();
    }, [path]);
    
    function search(queryString){
      setQuery(queryString);
      // getRecipe() <- removed
    }
    

    [path] 作为useEffect() 的依赖项提供,getRecipe() 将在path 更改时自动调用。所以我们不必从search() 手动调用它,因此可以从函数体中删除getRecipe()。这也使得当前的useEffect()(没有[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);
    }
    

    这确实需要将path 定义移动到getRecipe() 中。

    【讨论】:

      猜你喜欢
      • 2022-07-07
      • 2021-04-16
      • 2021-04-10
      • 2023-03-19
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多