反应.js控制台之间的状态发生了巨大变化.log而没有任何更改(在它已经正确更新自己之后)



一直在为我目前在编码类的家庭食谱项目工作。这一切都发生在我的create Recipe页面上,问题是我遇到了一个奇怪的事件,状态更新似乎是自己的。我有一个状态变量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个元素,而没有任何其他因素影响状态,调用nummofi的唯一行是console.log()的行。

我做错了什么?或者我不知道什么会导致这种情况发生?过去两天我一直在谷歌上搜索,没有任何结果,所以如果有任何建议或帮助,我将不胜感激。

第一个明显的问题是,你将反应节点存储在状态变量

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

而在下面你试图存储不同的类型

setNumOfI([...newArray])

表面上是一个数字。

我将首先查看这个状态变量的类型,您可能正在尝试存储一个数字,然后通过循环迭代呈现。

你应该考虑重新考虑你的配料数据结构,也许给它一个id字段,并且只存储你的状态中的配料数据。

相关内容

  • 没有找到相关文章

最新更新