[英]Console.log() after setState() doesn't return the updated state
[英]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.