我正在制作一个带有动态表单输入列表的网页,可以使用按钮添加或删除更多输入字段。我有一个父对象
<Ingredients />
,它跟踪输入并将它们作为子组件列表 <Ingredient />
保持在某种反应状态。每个 <Ingredient />
子级都有一个删除按钮,用于将它们从列表中删除,并传递一个函数回调 DeleteInput
,作为父级在单击时删除它们的道具。
问题是,当按下删除按钮时,该输入之后的所有字段也会消失。似乎是因为当调用回调时,函数内
inputList
的值是组件首次创建时的值。我怀疑 DeleteInput
函数是子组件闭包的一部分,即使它位于父组件中?
图像中显示的打印语句的输出突出了这一点。即使有 3 个输入形式,内部函数也只能看到第一个,因为这是创建时
inputList
的状态。
如何修复此错误,以便
inputList
函数内使用的 DeleteInput
的值是最新状态?我尝试使用react useCallback钩子,并将inputList
作为依赖项,但它有同样的问题。
// Parent
export function Ingredients() {
const [inputList, setInputList] = useState([]);
const [key, setKey] = useState(1);
function AddInput() {
setInputList(inputList.concat([<Ingredient
key={key}
index={key}
deleteInput={deleteInput}
/>]))
setKey(key+1);
}
// Approach 1 with regular function
function DeleteInput() {
console.log("Inside");
console.log(inputList);
let tmp = inputList;
tmp.splice(indexToDel, 1)
setInputList(tmp);
}
// Approach 2 with useCallback hook
const DeleteInput = useCallback((indexToDel) => {
console.log("Inside");
console.log(inputList);
let tmp = inputList;
tmp.splice(indexToDel, 1)
setInputList(tmp);
}, [inputList])
console.log("Outside");
console.log(inputList);
return (
<div>
{inputList}
<button type='button' onClick={AddInput}>Add More</button>
</div>
)
}
// Child
function Ingredient({index, deleteInput}) {
const i = index;
return (
<div className={styles.ingredient}>
<input className={styles.ingredientname} type='text' placeholder='Ingredient'></input>
<button type='button' onClick={() => DeleteInput(index)}>X</button>
</div>
)
}
Approach 1: Using a regular function:
function DeleteInput(indexToDel) {
console.log("Inside");
console.log(inputList);
let tmp = [...inputList]; // Create a copy of inputList
tmp.splice(indexToDel, 1);
setInputList(tmp);
}
方法2:使用useCallback钩子:
const DeleteInput = useCallback((indexToDel) => {
console.log("Inside");
console.log(inputList);
let tmp = [...inputList]; // Create a copy of inputList
tmp.splice(indexToDel, 1);
setInputList(tmp);
},
[输入列表]);