React:删除一个 children 而不再次渲染 parent
React: Delete one children without rendering the parent again
我有一个 parent component
,其中显示了 children
的列表。 child人是文学Cards
,每个card
都有一个delete button
。当我单击删除按钮时,整个 parent 和 children 会再次呈现,因此整个页面都会刷新。所以如果我是在文献卡列表的底部(例如 900 个文献卡)并删除最后一个文献卡,页面会刷新,因此我在页面的开头而不是页面的末尾(或任何我之前)。这有点烦人,因为我必须在删除 child 后向下滚动整个页面。
这基本上是我的 parent 代码:
class ProjectLiterature extends Component {
constructor(props) {
super(props);
this.state = {
literatureEntries: [],
}}
getLiteratureEntries(){
axios.get(`http://127.0.0.1:5000/getLiterature`)
.then(res => {
const literatureEntries = res.data;
this.setState({ literatureEntries })
})
}
deleteLiteratureEntry(id) {
axios.delete("http://127.0.0.1:5000/deleteLiterature", {
params: {
id
}
})
.then(res => {
// get current literature entries after deleting one file
this.getLiteratureEntries();
})
.catch(error => {
console.log(error)
})
}
render() {
const literatureEntries = this.state.literatureEntries
return (
{ literatureEntries.map((literature, index) =>
return (
<Literature literature={literature} key={literature._id}
deleteLiteratureEntry={this.deleteLiteratureEntry.bind(this)}
project_name={this.state.projectName}/>
)
})
}
)}
这基本上是我的 child 组件:
export default class Literature extends Component {
render() {
const literature = this.props.literature
return (
<Card>
<CardHeader>
{literature.title}
<Button className="float-right" onClick={() =>
this.props.deleteLiteratureEntry(literature._id}
</Button>
</CardHeader>
<CardBody>
...
</CardBody>
</Card>
)}}
那么我能做些什么来避免整个列表再次呈现吗?
parent 控制显示哪些 children,所以,当你删除一个 child 时,它的状态会改变,然后它需要 re-render 整个东西.
优化这个的想法是通过 React.memo
记忆 child 组件。
React memo 有第二个参数,它是一个函数,用于根据道具测试组件是否需要 re-render。
来自文档:
function MyComponent(props) {
/* render using props */
}
function areEqual(prevProps, nextProps) {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
}
export default React.memo(MyComponent, areEqual);
因此,当您要删除 child 时,parent 会收到通知并且 re-render 是其 children,而不会 re-render除非你告诉他们这样做。
PS:不建议一次显示900 children,用户会看到所有吗?可能是您需要设置分页以便仅显示 10/20 children.
您似乎在删除后重新获取列表。所以只是手动删除它而不是重新获取整个列表
deleteLiteratureEntry(id) {
axios.delete("http://127.0.0.1:5000/deleteLiterature", {
params: {
id
}
})
.then(res => {
let newList = this.state.literatureEntries.filter(item => item.id !== id);
this.setState({ literatureEntries: newList )}
})
.catch(error => {
console.log(error)
})
}
我有一个 parent component
,其中显示了 children
的列表。 child人是文学Cards
,每个card
都有一个delete button
。当我单击删除按钮时,整个 parent 和 children 会再次呈现,因此整个页面都会刷新。所以如果我是在文献卡列表的底部(例如 900 个文献卡)并删除最后一个文献卡,页面会刷新,因此我在页面的开头而不是页面的末尾(或任何我之前)。这有点烦人,因为我必须在删除 child 后向下滚动整个页面。
这基本上是我的 parent 代码:
class ProjectLiterature extends Component {
constructor(props) {
super(props);
this.state = {
literatureEntries: [],
}}
getLiteratureEntries(){
axios.get(`http://127.0.0.1:5000/getLiterature`)
.then(res => {
const literatureEntries = res.data;
this.setState({ literatureEntries })
})
}
deleteLiteratureEntry(id) {
axios.delete("http://127.0.0.1:5000/deleteLiterature", {
params: {
id
}
})
.then(res => {
// get current literature entries after deleting one file
this.getLiteratureEntries();
})
.catch(error => {
console.log(error)
})
}
render() {
const literatureEntries = this.state.literatureEntries
return (
{ literatureEntries.map((literature, index) =>
return (
<Literature literature={literature} key={literature._id}
deleteLiteratureEntry={this.deleteLiteratureEntry.bind(this)}
project_name={this.state.projectName}/>
)
})
}
)}
这基本上是我的 child 组件:
export default class Literature extends Component {
render() {
const literature = this.props.literature
return (
<Card>
<CardHeader>
{literature.title}
<Button className="float-right" onClick={() =>
this.props.deleteLiteratureEntry(literature._id}
</Button>
</CardHeader>
<CardBody>
...
</CardBody>
</Card>
)}}
那么我能做些什么来避免整个列表再次呈现吗?
parent 控制显示哪些 children,所以,当你删除一个 child 时,它的状态会改变,然后它需要 re-render 整个东西.
优化这个的想法是通过 React.memo
记忆 child 组件。
React memo 有第二个参数,它是一个函数,用于根据道具测试组件是否需要 re-render。
来自文档:
function MyComponent(props) {
/* render using props */
}
function areEqual(prevProps, nextProps) {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
}
export default React.memo(MyComponent, areEqual);
因此,当您要删除 child 时,parent 会收到通知并且 re-render 是其 children,而不会 re-render除非你告诉他们这样做。
PS:不建议一次显示900 children,用户会看到所有吗?可能是您需要设置分页以便仅显示 10/20 children.
您似乎在删除后重新获取列表。所以只是手动删除它而不是重新获取整个列表
deleteLiteratureEntry(id) {
axios.delete("http://127.0.0.1:5000/deleteLiterature", {
params: {
id
}
})
.then(res => {
let newList = this.state.literatureEntries.filter(item => item.id !== id);
this.setState({ literatureEntries: newList )}
})
.catch(error => {
console.log(error)
})
}