Это продолжение предыдущей статьи: Зачем писать свой React Data Grid в 2019 Для чего нужен Redux? Ответов много. Например, чтобы работать с общими данными в разных React-компонентах. Но можно воспринимать Redux еще как способ манипулирования компонентой. Сам взгляд интересный: любой React-компонент может управлять другим React-компонентом через Redux. Возьмём React-компоненту, которая отображает данные в виде строк и колонок (Data Grid, грид). Каким функционалом у нее можно управлять? Составом колонок и строк. Выделением. Хорошо бы и прокруткой данных.  Например, некая React-компонента (Some Сomponent) могла бы управлять гридом так: Управлять колонками не сложно. Достаточно положить в Redux настройки колонок: имена, порядок, ширины, маппинг на данные. Грид возьмет эти настройки и применит. С данными подход тот же. Но давайте усложним задачу. Предположим, строк очень много. Их нельзя разом загрузить с сервера, и нельзя разом отобразить. Поэтому нужна порционная загрузка данных и порционное отображение данных. Для порционного отображения возьмём виртуальный скроллинг, описанный в предыдущей статье. И попробуем скрестить его с порционной загрузкой и хранением в Redux. А также дадим возможность другим компонентам манипулировать загруженными данными и позицией скроллинга через Redux. Это не абстрактная задача, а реальная задача из разрабатываемой нами ECM-системы:
 Упорядочим требования. Что хотим получить? Эти задачи мы и рассмотрим. Небольшое отступление: виртуальный скроллинг из предыдущей статьи позволяет быстро проскроллить в любую часть грида. Например, в конец. Грид должен загрузить самую последнюю порцию данных, исключая все промежуточные, чтобы не тянуть с сервера тысячи строк. Поэтому порции не всегда загружаются последовательно, они могут быть загружены из разных частей списка. Мы выбрали следующую схему по загрузке-хранению данных:
 Грид в этой схеме делится на две части – компоненты Presentational и Container. Presentational занимается только отображением данных – это view. Данные показываются страницами (про это было рассказано в предыдущей статье). Container отвечает за загрузку данных и взаимодействие с Redux. Пройдёмся по стрелкам схемы: Приведу псевдокод этой схемы: Используемые типы в псевдокоде: С первой задачей справились — порционно загружать и хранить данные в Redux. Теперь перейдем к манипулированию. Самая частая задача — добавлять-удалять-изменять строки. Мы хотим, чтобы любая компонента веб-приложения могла это делать. Схема проста:  Some Component – это некоторая компонента веб-приложения, которая хочет управлять данными грида. Пройдёмся по схеме: Управлять скроллингом программно — это необходимый функционал. Самая распространенная ситуация — проскроллиться к выделенной записи. Например, пользователь создает новую запись в списке. Запись с учетом сортировки попадает в середину списка. Нужно программно выделить ее и проскроллиться к ней. И хорошо бы сделать это через Redux.  Управлять выделением через Redux не сложно, но как управлять скроллингом?
Для этого в Redux Store мы положим два поля: Поле scrollToIndex понятное. Хочешь выполнить скроллинг, тогда установи в scrollToIndex номер нужной строки. Этот номер будет передан гриду, и грид тут же выполнит скроллинг к ней:  Для чего поле scrollSignal? Оно решает проблему повторного скроллинга к тому же индексу. Если мы уже выполнили программный скроллинг к индексу 100, то повторно выполнить скроллинг к этому же индексу не получится. Поэтому используется поле scrollSignal, при изменении которого грид повторно выполнит скроллинг к scrollToIndex. ScrollSignal инкрементируется автоматически в редьюсере при обработке действия SCROLL:  Псевдокод управления скроллингом: Используемые типы в псевдокоде: Предложенные схемы взаимодействия с Redux, конечно же, не универсальны. Они подходят для разработанного нами грида, потому что мы оптимизировали грид под эти схемы, сделали у него соответствующее АПИ. Эти схемы не заработают для любого стороннего грида, поэтому воспринимайте статью, как один из примеров реализации взаимодействия с Redux. При разработке своего грида пришло понимание, что грид, в идеале, не часть нашего приложения, а независимый проект, который стоит выложить на github и развивать. Поэтому не стали использовать в коде предметные термины нашего приложения и добавлять лишние зависимости. Но с расширением функционала все сложнее этого придерживаться, ведь мы так и не выделили его в отдельный проект, а следовало сделать это сразу. Github все еще в планах. Писать свой грид — это было правильное для нас решение. У нас было достаточно времени, чтобы реализовать все, что хотели (виртуализацию, работу с redux, порционную загрузку, работу с клавиатуры, работу с колонками, like-поиск с подсветкой и многое другое). Изначально мы сильно вложились в сторонний грид, в надежде, что он взлетит на наших ситуациях. Используя его, мы поняли, как вообще работают гриды, какие существуют проблемы, как их надо решать, и что мы в итоге хотим получить. И сделали свое решение. C# programmer