Reactjs 使用shouldComponentUpdate时将删除子组件
我有三个部分:学期表、学期表和课程表Reactjs 使用shouldComponentUpdate时将删除子组件,reactjs,components,Reactjs,Components,我有三个部分:学期表、学期表和课程表 学期列表包含状态(包含所有学期及其内容的数组) 在课程组件中,我创建了shouldComponentUpdate()方法,以避免在课程未更改时呈现课程。如果没有这种方法,所有学期的所有课程都会重新呈现 但是,在添加课程后,当我修改添加课程以外的其他课程时,添加的课程将被删除 当我添加多个课程,然后尝试修改最初出现的课程时,也会发生同样的情况 我不知道为什么,但我认为这是由于shouldComponentUpdate()方法造成的 以下是shouldCompo
学期列表包含状态(包含所有学期及其内容的数组)
在课程组件中,我创建了shouldComponentUpdate()方法,以避免在课程未更改时呈现课程。如果没有这种方法,所有学期的所有课程都会重新呈现
但是,在添加课程后,当我修改添加课程以外的其他课程时,添加的课程将被删除
当我添加多个课程,然后尝试修改最初出现的课程时,也会发生同样的情况
我不知道为什么,但我认为这是由于shouldComponentUpdate()方法造成的
以下是shouldComponentUpdate():
shouldComponentUpdate(nextProps, nextState) {
if (JSON.stringify(this.props.course) === JSON.stringify(nextProps.course)) {
return false;
}
return true;
}
我在React文档中读到JSON.stringify()非常昂贵,但现在我将忽略这一点
学期组件中渲染方法的一部分:
{semester.courses.map(
course => (
<Course
key={course.id}
course={course}
semester={semester}
onInputChange={onInputChange}
onDeleteCourse={onDeleteCourse}
/>
)
)}
正如我前面所说的,我认为问题在于shouldComponentUpdate()方法,因为当它被注释掉时,一切都按预期进行。您正在将
课程
和学期
道具传递给
组件,但是您的JSON。stringify
比较只检查课程
每次添加/更改课程时,都要使用扩展运算符创建学期
和学期
的新副本。因此,您现有的未重新渲染的
组件将保留旧的组件。这就是当您更改任何现有课程时,新添加的课程将消失的原因,因为旧的学期
和学期课程
不包含新添加的课程
因此,要解决这个问题,您还需要将学期
包括在您的比较中
if (JSON.stringify(this.props.course) === JSON.stringify(nextProps.course) &&
JSON.stringify(this.props.semester) === JSON.stringify(nextProps.semester)
) {
return false;
}
上面的代码将修复您的问题,但不会阻止重新渲染其他课程
更好的设计是不将学期
道具传递给
组件。
但是如果这是不可避免的,那么也许不要创建新的学期
和学期
副本,并保持你的应该组件更新
handleInputChange = (event, course, semester) => {
const { name, value } = event.target;
var semesters = [...this.state.semesters];
var course = { ...course };
course[name] = value;
semester.courses[course.id-1] = course;
this.setState({ semesters });
}
handleAddCourse = semester => {
var semesters = [...this.state.semesters];
semester.courses.push({
// new course's id is obtained by incrementing last course's id which is the number of courses
id: semester.courses.length + 1,
name: '',
credit: 0,
markOver100: 0.0,
grade: '',
});
this.setState({ semesters });
}
您甚至不需要创建var semests=[…this.state.semests]的新副本代码>
handleInputChange = (event, course, semester) => {
const { name, value } = event.target;
course[name] = value;
this.setState(this.state); // enough to trigger re-render
}
handleAddCourse = semester => {
semester.courses.push({
id: semester.courses.length + 1,
name: '',
credit: 0,
markOver100: 0.0,
grade: '',
});
this.setState(this.state); // trigger re-render
}
在handleInputChange
和handledCourse
中打印以控制台您放入setState
的数据。你看到了什么?一个提琴或沙盒链接也很有用,谢谢你的详细解释。我有两个问题;1) 在哪些情况下,this.props.sement不等于nextrops.sement(在shouldComponentUpdate方法中)?!2) 我如何知道何时复制与何时不复制(仅分配引用)(例如何时执行foo=…bar vs foo=bar),因为这条语句seurm={…seurm}代码>在handleAddCourse
中,下一个渲染周期的学期将不一样。对于#2,我根据您的问题提出了一个黑客解决方案。通常不建议直接改变状态,您可以忽略我答案的最后一部分。正如我在回答中提到的,不要将整个学期
对象发送到
handleInputChange = (event, course, semester) => {
const { name, value } = event.target;
course[name] = value;
this.setState(this.state); // enough to trigger re-render
}
handleAddCourse = semester => {
semester.courses.push({
id: semester.courses.length + 1,
name: '',
credit: 0,
markOver100: 0.0,
grade: '',
});
this.setState(this.state); // trigger re-render
}