Реагировать: удалить одного потомка без повторного рендеринга родителя - PullRequest
0 голосов
/ 07 мая 2020

У меня есть parent component, где отображается список children. Дети - литература Cards и у каждого card есть delete button. Когда я нажимаю кнопку удаления, весь родитель и потомки снова отображаются, и поэтому вся страница обновляется. Итак, если я, например, нахожусь внизу списка литературных карточек (например, 900 литературных карточек) и удаляю последнюю литературную карточку, страница обновляется, и поэтому я нахожусь в начале страницы, а не в конце страницу (или где бы я ни был раньше). Это немного раздражает, потому что после удаления дочернего элемента мне приходится прокручивать всю страницу вниз.

Это в основном мой родительский код:

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

, и это в основном мой дочерний компонент:

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

Итак, есть ли что-нибудь, что я мог бы сделать, возможно, не снова отображается весь список?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

похоже, что вы обновляете свой список после удаления. поэтому вместо этого просто удалите его вручную, вместо того, чтобы повторно загружать весь список

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)
      })
  }
1 голос
/ 07 мая 2020

Родитель контролирует, какие дочерние элементы отображаются, поэтому, когда вы удаляете один дочерний элемент, его состояние изменяется, и затем ему необходимо повторно визуализировать весь материал.

Идея оптимизации этого заключается в том, чтобы сохранить дочерний компонент через React.memo. React memo имеет второй параметр, который является функцией, которая проверяет, нужно ли повторно отрисовывать компонент на основе свойств.

из документации:

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

Итак, когда вы удалит дочерний элемент, родитель будет уведомлен и повторно отобразит своих дочерних элементов, которые не будут повторно отображаться, если вы им не скажете.

PS: Показывать 900 дочерних элементов одновременно не рекомендуется, увидит ли пользователь все они ? возможно, вам нужно настроить разбиение на страницы так, чтобы отображалось только 10/20 дочерних элементов.

...