Рендеринг с рекурсией для вложенного списка в React - как избежать лишних обновлений?

У меня есть объект list в моем состоянии redux. Он имеет такой набор byId:

{
    root: {
        id: 'root',
        children: ['item_1', 'item_2'],
        data: 'Root String',
        parent: null,
    },
    item_1: {
        id: 'item_1',
        children: ['item_1_1', 'item_1_2', 'item_1_3'],
        data: 'Some String',
        parent: 'root',
    },
    item_1_1:
    {
        id: 'item_1_1'
        children: ['item_1_1_1', 'item_1_1_2']
        data: 'Some Other string',
        parent: 'item_1',
    },
    item_2: {
        ...
    }
    ...
}

Теперь я визуализирую приведенный выше список следующим образом:

оказывать()

recursiveRender = (component, idx = 0) => {
    const { data, children } = component;
    const { list } = this.props; 
    return (
        <div key = {idx}>
            {
                children.map((child, childIdx) =>
                    this.recursiveRender(list[child], childIdx))
            }
        </div>
    );
};

render() {
    const { list } = this.props;
    return this.recursiveRender(list.root);
}

Редукс Редукс

Я хочу обновить порядок дочерних элементов, скажем, item_1.

В моем действии redux я делаю следующее:

import update from 'immutability-helper';
...
...
return update(state,
    {
        list: {
            [parent]: {
                children: {
                    $splice: [[oldIdx, 1], [idx, 0, id]] },
                },
        },
    }
});

который действительно работает.

Проблема

Я заметил в React Dev Tools, что все (item_2 и item_3 тоже) рекурсивно визуализированного компонента перекрашивается. Понятия не имею почему. Я удостоверяюсь, что list неизменяем, но все дерево каждый раз рендерится заново. Как я могу убедиться, что перекрашена только измененная часть (здесь item_1) list?

Я не думаю, что использование reselect является решением здесь, поскольку список является действительно меняется.

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
217
1

Ответы 1

Функциональные компоненты без сохранения состояния не сравнивают предыдущие и новые свойства. Простым решением было бы использовать вместо этого PureComponent для вашего RecursiveRender.

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

Faizuddin Mohammed 27.10.2018 09:50

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

Ralph Najm 27.10.2018 09:59

Понятно. Да! Я бы попробовал. Но меня беспокоит, что функция «преобразование» каким-то образом будет зависеть от списка и все равно отреагирует на перерисовку. Я пытаюсь понять это.

Faizuddin Mohammed 27.10.2018 10:17

Что ж, если каждый из потомков является неизменяемым объектом, я думаю, это решит проблему.

Ralph Najm 27.10.2018 10:19

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

Faizuddin Mohammed 27.10.2018 10:35

Другие вопросы по теме