英文:
Passing array as from Parent to Child and getting back a filtered array in Parent
问题
在Child组件中,有一个删除按钮,点击它应该删除特定的数组元素并将更新后的数组发送回Parent。
它给出了以下输出
英文:
I have a Parent component and a Child component.
I am passing an Array from Parent to Child. I want the array to be filtered in the Child and that can be returned back to Parent.
After filtering in Child, it should return a filtered array.
Parent
const Parent = () =>{
const todoData = [
{id:0,todoname:"Study",todotoday:"Completing CSS today"},
{id:1,todoname:"Coding",todotoday:"Leetcode 2 Problems"}
];
const [myArray,setmyArray] = useState(todoData);
<div className="todomain">
{
myArray.map((obj)=>{
return ( <div className="todobox" key={obj.id}>
<div className="checkcont">
<img src={check} alt="Check" className='chkbtn btn'/>
</div>
<h2 className="head" >Todo: {obj.todoname}</h2>
<h3 className="todocont">{obj.todotoday}</h3>
<div className="todoboxbtn">
<Child todoList = {todoData} />
</div>
</div> )
})
}
</div>
}
Child
const Child = ({todoData}) =>{
onst [myArray,setmyArray] = useState(todoData);
const removeElm = (id) =>{
const myNewArray = myArray.filter((currElm)=>{
return currElm.id !== id;
})
setmyArray(myNewArray);
}
return (
<div className="todoicon">
{
myArray.map((obj)=>{
return ( <div className='todobtn' key={obj.props.id}>
<img src={del} alt="Delete" className='deleteBtn btn' onClick={() => removeElm(obj.props.id)}/>
</div>)
})
}
</div>
)
}
Expected:
In the Child component, there is a delete button, which on click should delete that particular Array element and send back the updated array to Parent.
It is giving the below output
答案1
得分: 2
如果您的目标是在用户从待办事项列表中删除项目时更改父组件的状态,那么您可以简单地将setter传递给子组件。
这样,您可以像这样调用您的组件:
<Child todoList={todoData} changeToDo={setmyArray}/>
并像这样更新您的子组件:
const Child = ({ todoData, changeToDo }) => {
const removeElm = (id) => {
changeToDo(myArray.filter((currElm) => {
return currElm.id !== id;
}))
}
return (
<div className="todoicon">
{
todoData.map((obj) => {
return (
<div className='todobtn' key={obj.id}>
<img src={del} alt="Delete" className='deleteBtn btn' onClick={() => removeElm(obj.id)}/>
</div>
)
})
}
</div>
)
}
请注意,将待办事项保存在子组件的状态中是不必要的。当您去更新父组件的状态时,将执行重新渲染,子组件将会得到其props的更新。
编辑 您期望的行为不会被渲染出来。事实上,您在父组件和子组件中都使用了map
迭代。
由于子组件显然只用于显示一个允许删除元素的图像,您不需要将整个TODO列表传递给它。您可以直接在props中将一个onClick
函数传递给它,并将它放在图像上。
您的父组件应该像这样:
import { useState } from 'react';
import { Child } from './test2';
const todoData = [
{ id: 0, todoname: 'Study', todotoday: 'Completing CSS today' },
{ id: 1, todoname: 'Coding', todotoday: 'Leetcode 2 Problems' },
];
const Parent = () => {
const [myArray, setmyArray] = useState(todoData);
const removeElm = (id) => {
const myNewArray = myArray.filter((currElm) => {
return currElm.id !== id;
});
setmyArray(myNewArray);
};
return (
<div className="todomain">
{myArray.map((obj) => {
return (
<div className="todobox" key={obj.id}>
<div className="checkcont">
<img src={check} alt="Check" className="chkbtn btn" />
</div>
<h2 className="head">Todo: {obj.todoname}</h2>
<h3 className="todocont">{obj.todotoday}</h3>
<div className="todoboxbtn">
<Child onDelete={() => removeElm(obj.id)} />
</div>
</div>
);
})}
</div>
);
};
您的子组件应该像这样:
export const Child = ({ onDelete }) => {
return (
<div className="todoicon">
<div className="todobtn">
<img
src={del}
alt="Delete"
className="deleteBtn btn"
onClick={onDelete}
/>
</div>
</div>
);
};
英文:
If your goal is to change the state of your parent component when the user deletes an item from your TODO list, then you can simply pass the setter to your child component.
In this way you can call your component like this:
<Child todoList = {todoData} changeToDo={setmyArray}/>
And update your child component like this:
const Child = ({todoData, changeToDo}) =>{
const removeElm = (id) =>{
changeTodo(myArray.filter((currElm)=>{
return currElm.id !== id;
}))
}
return (
<div className="todoicon">
{
todoData.map((obj)=>{
return (
<div className='todobtn' key={obj.id}>
<img src={del} alt="Delete" className='deleteBtn btn' onClick={() => removeElm(obj.id)}/>
</div>
)
})
}
</div>
)
}
Note that saving the Todo in a state of your child component is not necessary. When you go to update the state of the parent component, a re-render will be performed and your child will have its props updated
EDIT The behavior you expect is not the one that will be rendered. Indeed, you iterate with map
in the parent component and in the child component.
Since the child component apparently only serves to display an image allowing the element to be deleted, you don't need to pass the entire TODOList to it. You could directly pass it a onClick
function in props, and put it on your image.
Your parent component should be like this :
import { useState } from 'react';
import { Child } from './test2';
const todoData = [
{ id: 0, todoname: 'Study', todotoday: 'Completing CSS today' },
{ id: 1, todoname: 'Coding', todotoday: 'Leetcode 2 Problems' },
];
const Parent = () => {
const [myArray, setmyArray] = useState(todoData);
const removeElm = (id) => {
const myNewArray = myArray.filter((currElm) => {
return currElm.id !== id;
});
setmyArray(myNewArray);
};
return (
<div className="todomain">
{myArray.map((obj) => {
return (
<div className="todobox" key={obj.id}>
<div className="checkcont">
<img src={check} alt="Check" className="chkbtn btn" />
</div>
<h2 className="head">Todo: {obj.todoname}</h2>
<h3 className="todocont">{obj.todotoday}</h3>
<div className="todoboxbtn">
<Child onDelete={() => removeElm(obj.id)} />
</div>
</div>
);
})}
</div>
);
};
And you child component like this :
export const Child = ({ onDelete }) => {
return (
<div className="todoicon">
<div className="todobtn">
<img
src={del}
alt="Delete"
className="deleteBtn btn"
onClick={onDelete}
/>
</div>
</div>
);
};
答案2
得分: 2
父组件
// ...
const [filteredArray, setFilteredArray] = useState([]);//添加这个状态
// ...
子组件
// ...
const Child = ({todoList, setFilteredArray}) => {//还有你的 todoData 属性名应该是 todoList
// ...
英文:
You can simply create a new state in the parent and pass its setter function as a prop to the child and set the value using this setter function.
Parent
const Parent = () =>{
const todoData = [
{id:0,todoname:"Study",todotoday:"Completing CSS today"},
{id:1,todoname:"Coding",todotoday:"Leetcode 2 Problems"}
];
const [myArray,setmyArray] = useState(todoData);
const [filteredArray, setFilteredArray] = useState([]);//add this state
<div className="todomain">
{
myArray.map((obj)=>{
return ( <div className="todobox" key={obj.id}>
<div className="checkcont">
<img src={check} alt="Check" className='chkbtn btn'/>
</div>
<h2 className="head" >Todo: {obj.todoname}</h2>
<h3 className="todocont">{obj.todotoday}</h3>
<div className="todoboxbtn">
<Child todoList = {todoData} setFilteredArray={setFilteredArray} />
</div>
</div> )
})
}
{/* You can map filteredArray*/}
</div>
}
Child
const Child = ({todoList, setFilteredArray}) =>{//also your todoData prop name is todoList
const [myArray,setmyArray] = useState(todoData);
const removeElm = (id) =>{
const myNewArray = myArray.filter((currElm)=>{
return currElm.id !== id;
})
setmyArray(myNewArray);
setFilteredArray(myNewArray);
}
return (
<div className="todoicon">
{
myArray.map((obj)=>{
return ( <div className='todobtn' key={obj.props.id}>
<img src={del} alt="Delete" className='deleteBtn btn' onClick={() => removeElm(obj.props.id)}/>
</div>)
})
}
</div>
)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论