ReactJS - переключение видимости без повторного рендеринга - PullRequest
0 голосов
/ 03 июня 2018

Я использую ReactJS + nextJS + Semantic-UI-React

У меня есть ответ json, подобный этому.

[
    {
        "artist": "Cardi B",
        "dob": "01/01/1990",
        "albums":[
            {
                "title": "Invasion of privacy",
                "year": "2018"
            }
        ],
        "country": "usa"
    },
    {
        "artist": "Michael Jackson",
        "dob": "01/01/1950",
        "albums":[
            {
                "title": "Thriller",
                "year": "1981"
            },
            {
                "title": "Blood On The Dance Floor",
                "year": "1995"
            }           
        ],
        "country": "usa"
    }
]

Я хотел бы показать каждого художника в строке таблицы.Альбомы исполнителя отображаются при щелчке по какой-либо ячейке строки исполнителя.

У меня есть 2 компонента.Один для художника и один для альбома.AlbumTable компонент - это, по сути, еще одна таблица, обернутая внутри <Table.Row>.В основном приведенный ниже код работает просто отлично.

toggleVisibility(index){
    let oldSt = this.state.AlbumStatus;
    oldSt[index] = !oldSt[index];
    this.setState({AlbumStatus: oldSt});
}


renderResult(){
    let rows = this.props.artists.map((r, index) =>{
        return(
             <Table.Body key={index}>
                  <Table.Row >
                        <Table.Cell>{r.artist}</Table.Cell>
                        <Table.Cell>{r.dob}</Table.Cell>
                        <Table.Cell onClick={() => this.toggleVisibility(index)}>+</Table.Cell>                 
                        <Table.Cell>{r.country}</Table.Cell>                            
                  </Table.Row>
                  <AlbumRow result={r.albums} hiddenStatus={!this.state.AlbumStatus[index]} />
              </Table.Body>
        );
    });
    return rows;
}


render(){
    return(
      <Table > 
            <Table.Header >
              <Table.Row>
                <Table.HeaderCell >Artists</Table.HeaderCell>
                <Table.HeaderCell >Dob</Table.HeaderCell>
                <Table.HeaderCell >Albums</Table.HeaderCell>                                    
              </Table.Row>
            </Table.Header>
            {this.renderResult()}
       </Table>             
    );      
}

Мое требование - показывать альбомы только в том случае, если нажата кнопка «+» в строке артиста.Я могу переключать видимость, используя приведенный выше код.

Проблема:

Если я нажму знак «+» в строке «Майкл Джексон», его соответствующие альбомы будутотображается.однако все альбомы исполнителя также перерисованы.Это ожидается?Это вызовет проблемы с производительностью для больших наборов данных?Каков наилучший подход без существенного влияния на производительность?

1 Ответ

0 голосов
/ 03 июня 2018

Вероятно, не такая уж большая проблема, если вы не заметите, что с большими наборами данных дела идут медленно.Когда дело доходит до производительности, сначала оцените, если вы считаете, что у вас есть проблема ( Подробнее об измерении производительности React ).Не тратьте время на чрезмерную оптимизацию, пока не узнаете, что у вас есть проблема.

Как только вы можете разбить каждую строку на PureComponent:

import React, { PureComponent } 'react';

class AlbumTableRow extends PureComponent {
    render() {
        const {
            key,
            artist,
            dob,
            country
            albums,
            albumsHiddenStatus,
            onToggleVisibility,
        } = this.props;
        return(
            <Table.Body key={key}>
                <Table.Row >
                    <Table.Cell>{artist}</Table.Cell>
                    <Table.Cell>{dob}</Table.Cell>
                    <Table.Cell onClick={onToggleVisibility}>+</Table.Cell>
                    <Table.Cell>{country}</Table.Cell>
                </Table.Row>
                <AlbumRow result={albums} hiddenStatus={albumsHiddenStatus} />
            </Table.Body>
        );
    }
}

export default AlbumTableRow;

PureComponents должен перерисовываться только при изменении значения .Затем вы должны изменить код родительского компонента следующим образом:

getOnToggleVisibility = (index) => () => this.toggleVisibility(index);

renderResult(){
    let rows = this.props.artists.map((r, index) =>{
        return (
            <AlbumTableRow
                key={index}
                artist={r.artist}
                dob={r.dob}
                country={r.country}
                albums={r.albums}
                albumsHiddenStatus={!this.state.AlbumStatus[index]}
                onToggleVisibility={this.getOnToggleVisibility(index)}
            />
        );
    });
    return rows;
}

Обратите внимание, что я добавил метод getOnToggleVisibility, который берет этот индекс и возвращает функцию onToggleVisibility, которая знает правильный индекс для использования.

...