Javascript 在React中使用Immer按索引删除数组中的元素
我正在使用React构建这个组件,在这里我可以使用immer库添加、删除和编辑课程和章节。但是,当我添加一个新部分时,我似乎无法删除该部分中的特定课程,它会删除创建的最后一个课程。 删除特定的部分也不起作用。有人能给我一个关于这个问题的提示吗 这两个删除功能让我很为难:Javascript 在React中使用Immer按索引删除数组中的元素,javascript,reactjs,immer.js,Javascript,Reactjs,Immer.js,我正在使用React构建这个组件,在这里我可以使用immer库添加、删除和编辑课程和章节。但是,当我添加一个新部分时,我似乎无法删除该部分中的特定课程,它会删除创建的最后一个课程。 删除特定的部分也不起作用。有人能给我一个关于这个问题的提示吗 这两个删除功能让我很为难: remove = (sectionIndex, lessonIndex) => { const nextState = produce(this.state, (draftState) => {
remove = (sectionIndex, lessonIndex) => {
const nextState = produce(this.state, (draftState) => {
draftState.list[sectionIndex].lessons.splice(lessonIndex, 1);
});
this.setState(nextState);
this.id++;
};
deletesection(sectionIndex, i) {
const nextState = produce(this.state, (draftState) => {
draftState.list[sectionIndex].section.splice(i, 1);
});
this.setState(nextState);
this.id++;
}
这里是沙盒复制代码的链接:
删除实际上似乎对我有效,但我发现了删除部分的一些错误:
- 该函数接受两个参数(两个参数似乎都是节索引),但您只能用一个参数调用它
- 它不是箭头函数,因此它将有自己的
this
,并且将无法访问this.state
- 您正在访问一个似乎不存在的属性
.section
- 您希望从
draftState.list
数组中删除整个截面对象,而不是splice
我个人的偏好是使用curried函数,而不是将sectionIndex
一直传递到Lesson
组件。您也可以使用product
而不是直接访问this.state
。但这些只是建议。以下是我经过调整的版本:
import React from "react";
import "./styles.css";
import EdiText from "react-editext";
import produce from "immer";
import { v4 as uuid } from "uuid";
const Lesson = ({ lesson, onSave, remove }) => {
const { id } = lesson;
return (
<div key={id} id={`sectionlesson-${id}`}>
<div className="section-titles">
<i className="material-icons" id="iconsectionlist" type="button">
list
</i>
<EdiText
type="text"
value="Lesson Title"
onSave={onSave}
key={id}
id={`lesson-${id}`}
/>
<i className="material-icons" id="iconsectiondel" type="button">
text_fields
</i>
<i className="material-icons" id="iconsectiondel" type="button">
smart_display
</i>
<i
className="material-icons"
id="iconsectiondel"
onClick={remove}
type="button"
>
delete
</i>
</div>
<div className="testh"></div>
</div>
);
};
const Section = ({ section, onSave, remove, addlesson, deletesection }) => {
const { id } = section;
return (
<div key={id} id={`sds-${id}`}>
<div className="course-structure-form" key={id} id={`csf1-${id}`}>
<div className="section-heading">
<i className="material-icons" id="iconsection">
api
</i>
<EdiText type="text" value="Section Title" onSave={onSave} />
</div>
{section.lessons.map((lesson, lessonIndex) => (
<Lesson
key={lesson.id}
lesson={lesson}
remove={remove(lessonIndex)}
onSave={onSave}
/>
))}
<div className="addnewlesson" onClick={addlesson}>
<i
className="material-icons"
id="iconsectionde"
role="button"
type="button"
>
add_circle
</i>
<span>Add New Lesson</span>
</div>
<button onClick={deletesection}>Delete Section</button>
</div>
</div>
);
};
class TestClonereact extends React.Component {
constructor(props) {
super(props);
this.state = {
list: []
};
}
onSave = (val) => {
console.log("Edited Value -> ", val);
};
lesson({ id }) {}
addsection = () => {
this.setState(
produce((draftState) => {
draftState.list.push({ id: uuid(), lessons: [] });
})
);
};
addlesson = (sectionIndex) => () => {
this.setState(
produce((draftState) => {
// needs to have a unique id
draftState.list[sectionIndex].lessons.push({ id: uuid() });
})
);
};
remove = (sectionIndex) => (lessonIndex) => () => {
this.setState(
produce((draftState) => {
draftState.list[sectionIndex].lessons.splice(lessonIndex, 1);
})
);
};
deletesection = (sectionIndex) => () => {
this.setState(
produce((draftState) => {
delete draftState.list[sectionIndex];
})
);
};
render() {
return (
<div>
{this.state.list.map((section, i) => (
<Section
key={section.id}
section={section}
remove={this.remove(i)}
addlesson={this.addlesson(i)}
onSave={this.onSave}
deletesection={this.deletesection(i)}
/>
))}
<div className="add-section-button-structure">
<button className="tablink" onClick={this.addsection}>
Add New Section
</button>
<button className="tablink">Clear</button>
<button className="tablink">Preview</button>
<button className="tablink">Submit</button>
</div>
</div>
);
}
}
export default TestClonereact;
从“React”导入React;
导入“/styles.css”;
从“反应编辑文本”导入编辑文本;
从“伊默”进口农产品;
从“uuid”导入{v4 as uuid};
const-Lesson=({Lesson,onSave,remove})=>{
const{id}=lesson;
返回(
列表
文本字段
智能显示
删除
);
};
const Section=({Section,onSave,remove,addlessource,deletesection})=>{
const{id}=节;
返回(
应用程序编程接口
{section.lessons.map((lesson,lessonIndex)=>(
))}
加上一个圆圈
添加新课程
删除节
);
};
类TestClonereact扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
名单:[]
};
}
onSave=(val)=>{
console.log(“编辑值->”,val);
};
课程({id}){}
addsection=()=>{
这是我的国家(
生产((绘图状态)=>{
push({id:uuid(),课程:[]});
})
);
};
addlesson=(sectionIndex)=>()=>{
这是我的国家(
生产((绘图状态)=>{
//需要有一个唯一的id
draftState.list[sectionIndex].lessons.push({id:uuid()});
})
);
};
删除=(节索引)=>(lessonIndex)=>()=>{
这是我的国家(
生产((绘图状态)=>{
draftState.list[sectionIndex].lessons.splice(lessonIndex,1);
})
);
};
deletesection=(sectionIndex)=>()=>{
这是我的国家(
生产((绘图状态)=>{
删除draftState.list[节索引];
})
);
};
render(){
返回(
{this.state.list.map((节,i)=>(
))}
添加新节
清楚的
预览
提交
);
}
}
导出默认TestClonereact;
deletesection的第二个参数是什么?你怎么称呼它?@quirimo“i”是节索引,我通过返回节中的映射来称呼它,但我无法单独删除每个节,我想到的最好的办法是在一次单击中删除所有部分。我可能错了,但在上面的代码片段中,我没有看到fn被调用anywhere@quirimmo你说fn是什么意思?fn是功能的捷径谢谢,这正是我想做的,更感谢你在我做错的事情中为我打破了它。
import React from "react";
import "./styles.css";
import EdiText from "react-editext";
import produce from "immer";
import { v4 as uuid } from "uuid";
const Lesson = ({ lesson, onSave, remove }) => {
const { id } = lesson;
return (
<div key={id} id={`sectionlesson-${id}`}>
<div className="section-titles">
<i className="material-icons" id="iconsectionlist" type="button">
list
</i>
<EdiText
type="text"
value="Lesson Title"
onSave={onSave}
key={id}
id={`lesson-${id}`}
/>
<i className="material-icons" id="iconsectiondel" type="button">
text_fields
</i>
<i className="material-icons" id="iconsectiondel" type="button">
smart_display
</i>
<i
className="material-icons"
id="iconsectiondel"
onClick={remove}
type="button"
>
delete
</i>
</div>
<div className="testh"></div>
</div>
);
};
const Section = ({ section, onSave, remove, addlesson, deletesection }) => {
const { id } = section;
return (
<div key={id} id={`sds-${id}`}>
<div className="course-structure-form" key={id} id={`csf1-${id}`}>
<div className="section-heading">
<i className="material-icons" id="iconsection">
api
</i>
<EdiText type="text" value="Section Title" onSave={onSave} />
</div>
{section.lessons.map((lesson, lessonIndex) => (
<Lesson
key={lesson.id}
lesson={lesson}
remove={remove(lessonIndex)}
onSave={onSave}
/>
))}
<div className="addnewlesson" onClick={addlesson}>
<i
className="material-icons"
id="iconsectionde"
role="button"
type="button"
>
add_circle
</i>
<span>Add New Lesson</span>
</div>
<button onClick={deletesection}>Delete Section</button>
</div>
</div>
);
};
class TestClonereact extends React.Component {
constructor(props) {
super(props);
this.state = {
list: []
};
}
onSave = (val) => {
console.log("Edited Value -> ", val);
};
lesson({ id }) {}
addsection = () => {
this.setState(
produce((draftState) => {
draftState.list.push({ id: uuid(), lessons: [] });
})
);
};
addlesson = (sectionIndex) => () => {
this.setState(
produce((draftState) => {
// needs to have a unique id
draftState.list[sectionIndex].lessons.push({ id: uuid() });
})
);
};
remove = (sectionIndex) => (lessonIndex) => () => {
this.setState(
produce((draftState) => {
draftState.list[sectionIndex].lessons.splice(lessonIndex, 1);
})
);
};
deletesection = (sectionIndex) => () => {
this.setState(
produce((draftState) => {
delete draftState.list[sectionIndex];
})
);
};
render() {
return (
<div>
{this.state.list.map((section, i) => (
<Section
key={section.id}
section={section}
remove={this.remove(i)}
addlesson={this.addlesson(i)}
onSave={this.onSave}
deletesection={this.deletesection(i)}
/>
))}
<div className="add-section-button-structure">
<button className="tablink" onClick={this.addsection}>
Add New Section
</button>
<button className="tablink">Clear</button>
<button className="tablink">Preview</button>
<button className="tablink">Submit</button>
</div>
</div>
);
}
}
export default TestClonereact;