簡體   English   中英

React.js 狀態在 console.log 之間發生了巨大變化而沒有任何改變(在它已經正確更新之后)

[英]React.js State changes drastically between console.log's without anything changing it (after it already updated itself properly)

一直在為我目前所在的編碼課程開展家庭食譜項目。這一切都發生在我的創建食譜頁面上,問題是我遇到了一個奇怪的事件,狀態更新似乎是它自己的。 我有一個狀態變量numOfI (成分的數量),它保存我在頁面上創建的組件數組和幾個函數,用於在狀態數組中添加和刪除我創建的組件。 通過這種方式,用戶可以添加和刪除盡可能多的成分,並最終根據需要進行操作。 這是 RecipeNew 頁面的代碼:

import { useEffect, useState } from 'react';
import { createRecipe } from '../services/recipeService';
import IngredientInput from '../componenets/IngredientInput';

export default function RecipeNew(props) {

    const [formState, setFormState] = useState({
        creator: '',
        access: '',
        name: '',
        ingredients: [{ amount: '', ingred: '' }],
        steps: []
    });

    const [numOfI, setNumOfI] = useState([<IngredientInput first='true' onChange={handleChange}
    key={0}/>]);
   

    const [numOfSteps, setNumOfSteps] = useState([]);

    console.log(numOfI);

    async function handleSubmit(event) {
        event.preventDefault();
        console.log(formState);


        createRecipe(formState);
        setFormState({
            creator: '',
            access: '',
            name: '',
            ingredients: [{ amount: '', ingred: '' }],
            steps: []
        });
        props.history.push('/home');

    }

    function handleChange(event) {
        console.log(event.target)
        setFormState({ ...formState, [event.target.name]: event.target.value });
    }


    function handleAdditionalIngredient() {

        const newArray = [];
        newArray.push(
            <IngredientInput pos={numOfI.length} key={numOfI.length} handleRemoveIngredient={handleRemoveIngredient}
                handleChange={handleChange}
                setNumOfI={setNumOfI} numOfI={numOfI} />)
        setNumOfI(prevArray => [...prevArray, ...newArray]);


        console.log('numOfI');
        console.log(numOfI);

    }

    function handleRemoveIngredient(pos) {

        const newArray = [];

        console.log('numOfI before removal');
        console.log(numOfI)
        console.log('Pos Removed')
        console.log(pos)
        console.log('---------------')

        // numOfI.forEach((ing, i) => {
        //     console.log('Ingred:')
        //     console.log(ing);
        //     console.log(' ');

        //     if(pos === i){
        //         return;
        //     } else{
        //         newArray.push(ing);
        //     }


        // });
        console.log('================')
        // console.log('New Array')
        // console.log(newArray)
        // setNumOfI([...newArray])
        console.log('Num Of I')
        console.log(numOfI)
    }

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <div className='ingred'>
                    <input type='text' name='name'
                        placeholder='Name' onChange={handleChange} />

                    {numOfI}

                    <button type="button" onClick={handleAdditionalIngredient}>+</button>
                </div>

                <div className='steps'>
                    <textarea cols="40" rows="5" type="" name='steps[]' placeholder={`Step ${numOfSteps + 1}`} />
                </div>
                <button>Submit</button>
            </form>
        </div>
    );
}

以及我創建的組件的代碼(以防萬一):

export default function IngredientInput(props){
    const amount= `amount[${(props.pos)+1}]`
    const ingred= `ingredients[${(props.pos)+1}].ingred`

    const checkFirst = props.first === 'true' ? <></> : 
    <button onClick={() => props.handleRemoveIngredient(props.pos)} 
            type='button'>-</button>
       

    return(
        <div>
            <input type='text' name={amount} 
                onChange={props.handleChange} placeholder='#'/>

            <input type='text' name={ingred}
                onChange={props.handleChange} placeholder='Ingredient'/>

            {checkFirst}  
        </div>
    );
}

添加帶有handleAdditionalIngredient項目會正確調整狀態,更新發生在函數之外,因為內部的 console.log 對於狀態的異步性質來說太快了,但它確實可以正確更新。

當我嘗試使用handleRemoveIngredient刪除項目時出現問題。 隨着所有調整 numOfI 狀態的代碼被注釋掉,不知何故在我的 const [state] 聲明之后的 console.log 和handleRemoveIngredient的第一行之間,狀態已經完全改變了。 下面的瀏覽器控制台示例,但發生的另一件事是我按了 + ( handleAdditionalIngredient ) 按鈕三次,然后按了被剝離的 - ( handleRemoveIngredient ) 按鈕一次。

RecipeNew.js:57 numOfI
RecipeNew.js:58 [{…}]           //Inside the handleAdditonalIngredient
RecipeNew.js:22 (2) [{…}, {…}]   // In the main RecipeNew function
RecipeNew.js:57 numOfI
RecipeNew.js:58 (2) [{…}, {…}]
RecipeNew.js:22 (3) [{…}, {…}, {…}]
RecipeNew.js:57 numOfI
RecipeNew.js:58 (3) [{…}, {…}, {…}]
RecipeNew.js:22 (4) [{…}, {…}, {…}, {…}]   
RecipeNew.js:66 numOfI before removal
RecipeNew.js:67 (2) [{…}, {…}]

正如您所看到的,狀態從數組中的 4 個元素急劇更改為 2 個元素,而沒有任何其他影響狀態,調用 numOfI 的唯一行是 console.log()。

我究竟做錯了什么? 或者我不知道什么會導致這種情況發生? 過去兩天我一直在用谷歌搜索沒有任何成功,所以任何見解/幫助將不勝感激。

第一個明顯的即時錯誤是您將反應節點存儲在狀態變量中

const [numOfI, setNumOfI] = useState([<IngredientInput first='true' onChange={handleChange}
    key={0}/>]);
   

在更進一步的地方,您試圖存儲不同的類型

setNumOfI([...newArray])

表面上是一個數字。

我將首先查看此狀態變量的類型,您可能正在嘗試存儲一個數字,然后通過遍歷循環進行渲染。

您應該考慮重新考慮您的 Ingredient 數據結構,也許給它一個id字段,並僅存儲您所在州的成分數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM