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)
      })
  }