React re render array, тогда как ключ элемента не изменился

Очень простой пример кода списка:

class List extends React.Component {
    render() {
        const listComponent = this.props.numbers.map((number) =>
            <Item key={ number.toString() } value={ number } />,
        );

        return (
            <div>
                <button onClick={ () => this.setState({ test: 1 })}>Re-render list</button>
                { listComponent }
            </div>
        );
    }
}

А вот этот пункт:

class Item extends React.Component {
    render() {
        return (
            <div>{ this.props.value + ', rendered time:' + new Date().getTime() }</div>
        );
    }
}

Когда я нажимаю кнопку, состояние обновляется, поэтому компонент List повторно отображается.

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

Может кто-нибудь объяснить мне, почему?


person vital    schedule 28.07.2017    source источник


Ответы (3)


Ваше понимание совершенно неверно

Вся цель key для ordering, а не rendering. Представьте, что у вас есть элементы a, b, c, d, и измените их порядок переключателями a и c, то есть c, b, a, d. Без ключа реакции крайне сложно понять, как преобразовать старый виртуальный DOM в новый виртуальный DOM.

Пожалуйста, прочитайте это https://facebook.github.io/react/docs/lists-and-keys.html

person Guichi    schedule 28.07.2017

При повторном рендеринге компонента вы также запускаете цепную реакцию повторного рендеринга всех дочерних компонентов.

Если вы хотите предотвратить повторный рендеринг дочернего компонента (например, если некоторые из переданных реквизитов не изменились), вы можете использовать метод жизненного цикла shouldComponentUpdate().

class Item extends React.Component {
    shouldComponentUpdate(nextProps) {
        // only re-render if props.value has changed
        return this.props.value !== nextProps.value;
    }

    render() {
        return (
            <div>{ this.props.value + ', rendered time:' + new Date().getTime() }</div>
        );
    }
}
person Tom Van Rompaey    schedule 28.07.2017
comment
Я это понимаю, но тогда какой смысл иметь ключевые свойства для элементов массива? - person vital; 28.07.2017
comment
Насколько я понимаю, эти ключи — просто оптимизация производительности для сравнения, изменилось ли что-то в элементах списка. Ничего общего с повторным рендерингом или не повторным рендерингом. Вот подробное объяснение того, зачем нужны ключи: facebook. github.io/react/docs/ - person Tom Van Rompaey; 28.07.2017

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

person Legolas    schedule 28.07.2017