【问题标题】:Recipe gets posted but doesn't get saved食谱已发布但未保存
【发布时间】:2020-12-20 12:32:16
【问题描述】:

我正在使用 react 和 axios 创建一个食谱应用程序。当我尝试通过在 form.js 中提交表单来添加新配方时,它不会与其他配方一起保存和显示,它只会在控制台中打印。我想这与axios有关。任何想法?。感谢任何建议,伙计们full code

form.js

import React from 'react'
import './Form.css'
import {RecipeContext} from './RecipeContext';
import {useContext,useState,useEffect} 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=e=>{
     
      e.preventDefault()
      const newRecipe={name:nazev,description:postup,ingredients:[ingredience],duration:+time,info:uvodni}
      
      
      
      axios.post("https://cookbook.ack.ee/api/v1/recipes", newRecipe)
      .then(res => setRecipes(res.data))
      .catch(error => console.log(error));
      
      
    
    }
    
    return (
        <>
        <button className="pridat" onClick={onSubmit}>+</button>
        <form className="form" >
          <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>+ Přidat</button>
          <input type="text" className="postup" placeholder="Postup"
          value={postup}
          onChange={(e) => setPostup(e.target.value)}/>
         <input type="text" placeholder="Čas" className="cas" value={time}
          onChange={(e) => setTime(e.target.value)}/>
          
        </form>
        </>
    )
          }

export default Form

recipelist.js

import {RecipeContext} from './RecipeContext';
import {useContext} from 'react';
import Recipe from './Recipe';
import './RecipeList.css'
import {Link} from 'react-router-dom'

function RecipeList() {

 const {recipes}=useContext(RecipeContext)
  
  return (
<>
<div className="navbar">
    <h1>Recepty</h1>
    <h3>Počet receptů:{recipes.length}</h3>
  <Link to="/pridat-recept"> <h2 className="plus">+</h2></Link> 
</div>
<div className="recipe-list">
{recipes.map(item=>(
    <Recipe name={item.name} id={item.id} duration={item.duration} score={item.score} key={item.id}/>
))}
</div>
</>

  );
}

export default RecipeList;

recipecontext.js

import React,{useState,useEffect,createContext,useReducer} from 'react';
import axios from 'axios';
import AppReducer from './AppReducer'


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

export default function RecipeProvider(props) {
    const[recipes,setRecipes]=useState([])
    const[state,dispatch]=useReducer(AppReducer,recipes)
    function addRecipe(id){
      dispatch({
        type:'ADD_RECIPE',
        payload:id
      })
    }
  
    useEffect(() => {
  axios.get('https://cookbook.ack.ee/api/v1/recipes?limit=10&offset=0')
  .then(res=>setRecipes(res.data))
  console.log(recipes)
    })   

    
  

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

appreduce.js

export default (state,action)=>{
    switch(action.type){
  
        case 'ADD_RECIPE':
            return{
                ...state,
                recipes:[action.payload,...state.recipes]
            }
        default:
            return state;
    }
}

【问题讨论】:

  • 添加RecipeContext相关的代码。您的食谱是否已保存在后端?
  • 我已经加进去了
  • 上下文的值似乎是一个具有三个属性的对象,但传递给createContext([[],() =&gt; {}]) 的初始值是一个数组。同样在reducer中,最好在最后添加新的payload,这样旧的值就不会覆盖它,比如recipes:[...state.recipes, action.payload]。菜谱的数据类型是什么?
  • 我现在意识到来自 recipecontext 的 addrecipe 函数没有在表单中使用......所以这不是为什么它没有被保存到后端吗?
  • addRecipe 在您的情况下将食谱添加到食谱数组中,如果食谱没有保存在后端,这可能不是原因。此外,您还有一个 setRecipes 函数,用于在发布请求后更新 FE 中的配方。纠正我上面提到的所有事情,并确保这不是后端的问题。

标签: reactjs axios react-context


【解决方案1】:

由于食谱 API 随时为您提供食谱列表,因此您可以使用它来更新应用中的食谱。

const onSubmit = (e) => {
    e.preventDefault();
    const newRecipe = {
      name: nazev,
      description: postup,
      ingredients: [ingredience],
      duration: +time,
      info: uvodni,
    };

    axios
      .post('https://cookbook.ack.ee/api/v1/recipes', newRecipe)
      .then((res) => {
        console.log(res.data); // confirm if it's the new recipe
        updateRecipes();
      })
      .catch((error) => console.log(error));
  };

在上下文中,您可以向useEffect 添加一个空数组,仅在组件挂载时运行该数组,并且可以将updateRecipes 函数放置在这里,因为这是我们希望在上下文中的一件事:

const [recipes, setRecipes] = useState([]);
  // the state below is not being used anywhere so I commented it
  // const [state, dispatch] = useReducer(AppReducer, { recipes });
  const updateRecipes = (id) => {
    axios
      .get('https://cookbook.ack.ee/api/v1/recipes?limit=1000&offset=0')
      .then((res) => setRecipes(res.data));
  };

  useEffect(() => {
    axios
      .get('https://cookbook.ack.ee/api/v1/recipes?limit=1000&offset=0')
      .then((res) => setRecipes(res.data));
  }, []);

【讨论】:

    【解决方案2】:

    一种解决方案是获取配方上下文,然后附加新配方(假设您的 axios 帖子已成功添加到数据库中)。

          axios.post("https://cookbook.ack.ee/api/v1/recipes", newRecipe)
          .then(res => setRecipes(res.data))
          .catch(error => console.log(error));
    

          axios.post("https://cookbook.ack.ee/api/v1/recipes", newRecipe)
          .then(res => setRecipes({
            ...recipes,
            newRecipe
          }))
          .catch(error => console.log(error));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-26
      • 2018-03-20
      • 2017-08-16
      • 1970-01-01
      • 2022-08-23
      • 2014-11-06
      • 2015-01-14
      相关资源
      最近更新 更多