You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Axios添加食谱失败求助(附完整代码)

问题分析与解决方案

我来帮你梳理下代码里的几个关键问题,这些应该就是导致食谱无法成功添加的核心原因:


1. Axios.post 未传递请求体且无错误处理

你当前的axios.post只传入了API地址,但没有把新建的食谱数据发送给后端,而且没有处理请求的成功/失败回调——这就是为什么没有报错,但数据也没加上的主要原因。另外,你创建的newRecipe里还漏掉了ingredience字段,大概率后端接口是需要这个参数的。

2. Context 中状态管理逻辑混乱

你在RecipeContext里同时混用了useState和useReducer,而且还存在命名错误:定义的方法是addRecipe,但Provider里却写了addTransaction,这会导致调用时直接报错。另外AppReducer的逻辑也不对,你初始传入的state是数组,但reducer里却试图访问state.recipes,这完全不匹配。

3. 表单提交逻辑问题

页面里有两个按钮:一个是外部的+按钮调用onSubmit,另一个是表单内的+ Přidat按钮——这个按钮默认是submit类型,会触发表单的默认提交行为(页面刷新),而且你没有阻止它。另外onSubmit里的逻辑顺序也不对,应该先阻止默认行为,再处理数据。

4. useEffect 无限循环请求

RecipeProvider里的useEffect没有添加依赖数组,会导致组件每次渲染都重复调用axios.get,造成无限循环请求API。


修改后的代码示例

Form.js

import React from 'react'
import './Form.css'
import { RecipeContext } from './RecipeContext';
import { useContext, useState } from 'react';
import axios from 'axios';

function Form() {
  const [nazev, setNazev] = useState('');
  const [uvodni, setUvodni] = useState('');
  const [ingredience, setIngredience] = useState('');
  const [postup, setPostup] = useState('');
  const [time, setTime] = useState(0);
  const [score, setScore] = useState(0);
  const { recipes, setRecipes } = useContext(RecipeContext);

  const onSubmit = async (e) => {
    // 先阻止默认提交行为
    e.preventDefault();
    
    // 确保所有必填字段都有值(可以根据API要求调整)
    if (!nazev || !ingredience || !postup) {
      alert('请填写必填字段!');
      return;
    }

    const newRecipe = {
      id: Math.floor(Math.random() * 100000000),
      description: postup,
      name: nazev,
      duration: time,
      info: uvodni,
      score: +score,
      ingredience: ingredience // 补上漏掉的字段
    };

    try {
      // 发送POST请求,传递食谱数据
      const res = await axios.post("https://cookbook.ack.ee/api/v1/recipes", newRecipe);
      // 确认API返回成功后,再更新本地状态
      setRecipes([...recipes, res.data]);
      // 清空表单输入
      setNazev('');
      setUvodni('');
      setIngredience('');
      setPostup('');
      setTime(0);
      setScore(0);
      alert('食谱添加成功!');
    } catch (err) {
      // 捕获并打印错误,方便调试
      console.error('添加食谱失败:', err.response?.data || err.message);
      alert('添加失败,请检查控制台信息!');
    }
  };

  return (
    <>
      <button className="pridat" onClick={onSubmit}>+</button>
      <form className="form" onSubmit={onSubmit}>
        <p className="nazev">Název receptu</p>
        <input type="text" value={nazev} onChange={(e) => setNazev(e.target.value)} />
        <input type="text" className="uvodni" placeholder="Úvodní text" value={uvodni} onChange={(e) => setUvodni(e.target.value)} />
        <h2>Ingredience</h2>
        <input placeholder="Vaše ingredience" type="text" value={ingredience} onChange={(e) => setIngredience(e.target.value)} />
        {/* 把这个按钮改成button类型,避免触发表单默认提交 */}
        <button type="button">+ Přidat</button>
        <input type="text" className="postup" placeholder="Postup" value={postup} onChange={(e) => setPostup(e.target.value)} />
        <input type="number" placeholder="Čas" className="cas" value={time} onChange={(e) => setTime(e.target.value)} />
      </form>
    </>
  );
}

export default Form;

RecipeContext.js

import React, { useState, useEffect, createContext } from 'react';
import axios from 'axios';

export const RecipeContext = createContext([[], () => {}]);

export default function RecipeProvider(props) {
  const[recipes,setRecipes]=useState([])

  useEffect(() => {
    // 添加空依赖数组,只在组件挂载时请求一次
    axios.get('https://cookbook.ack.ee/api/v1/recipes?limit=10&offset=0')
      .then(res=>setRecipes(res.data))
      .catch(err => console.error('获取食谱列表失败:', err))
  }, [])

  return (
    <RecipeContext.Provider value={{recipes,setRecipes}}>
      {props.children}
    </RecipeContext.Provider>
  )
}

额外调试建议

  1. 打开浏览器的开发者工具(F12),切换到Network标签,查看POST请求的状态码和响应内容,确认后端是否返回了错误信息。
  2. 确认后端API的请求参数要求,比如字段名是否和你发送的一致(比如ingredience是否需要复数形式ingredients)。
  3. 测试时可以先在onSubmit里console.log(newRecipe),确认数据格式是否正确。

内容的提问来源于stack exchange,提问作者jendazedniik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:05:30