Как получить атрибуты в блоке Гутенберг?

Вопрос или проблема

У меня есть компонент, который управляет массивом изображений (выбираются с помощью Media Picker через компонент MediaUpload). Изображения хранятся в виде массива. У меня есть функции для добавления, удаления и изменения изображения.

attributes: {
        images : {type: 'array', default: []} 
   
}

Это функция удаления. Она определена внутри основной функции редактирования блока. Ей передается индекс в массиве изображения для удаления:

const removeMedia = (idx) => {
        let images = structuredClone(attributes.images); 
        let newImages = [];
            
        for (let i = 0; i < images.length; i++)
        {
            if (i != idx)
            {
                    newImages.push(images[i]);
            }
       }

       setAttributes({
            images: newImages
       });
}

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

Также, мне было бы лучше модифицировать атрибуты?

(Мне не важно, что мой метод удаления элемента из массива немного громоздкий).

.

Ответ или решение

Чтобы ответить на вопрос, как получить атрибуты в блоке Gutenberg и как правильно с ними работать, необходимо подробно рассмотреть структуру и логику работы с Gutenberg-блоками в контексте разработки плагинов и тем для WordPress.

Теория

Gutenberg — это редактор блоков, представленный в WordPress, который позволяет пользователям создавать контент с использованием различных типов блоков. Каждый блок имеет свои атрибуты (properties), которые представляют собой данные, определяющие, как блок отображает и ведет себя. Атрибуты хранятся на уровне компонента React для поддержания функциональности блока.

Для управления состоянием блока (в том числе его атрибутами) используется хук useBlockProps, предоставленный библиотекой @wordpress/block-editor. Атрибуты определяются в регистрации блока через registerBlockType, где их типы и значения по умолчанию задаются в объекте attributes.

В вашем сценарии атрибуты определяются как массив изображений:

attributes: {
    images: { type: 'array', default: [] }
}

Функция удаления removeMedia манипулирует этим массивом, удаляя элемент с заданным индексом, и обновляет состояние блока вызовом setAttributes, что вызывает повторный рендер блока.

Пример

Вы предоставили функцию для удаления элемента из массива изображений, которая выглядит следующим образом:

const removeMedia = (idx) => {
    let images = structuredClone(attributes.images);
    let newImages = [];

    for (let i = 0; i < images.length; i++) {
        if (i != idx) {
            newImages.push(images[i]);
        }
    }

    setAttributes({
        images: newImages
    });
}

Эта функция сначала клонирует текущий массив изображений, затем создает новый массив, исключая индекс для удаления, и обновляет атрибут images с помощью функции setAttributes. В вашем коде используется метод structuredClone, который является современным способом глубокого копирования объектов и массивов в JavaScript.

Применение

  1. Оптимизация логики управления атрибутами:
    Использование setAttributes является правильным подходом для обновления состояния блока, так как это приводит к автоматическому повторному рендеру блока с обновленным состоянием. Таким образом, ваша логика удаления изображений из массива довольно верна, хотя поиск более оптимального метода избавления от элементов массива, например, использованием методов filter или splice, мог бы сделать код более лаконичным и читабельным:

    const removeMedia = (idx) => {
       const newImages = attributes.images.filter((_, index) => index !== idx);
       setAttributes({ images: newImages });
    }
  2. Изменение атрибутов:
    Изменять атрибуты напрямую (например, attributes.images[idx] = ...) небезопасно, так как это приводит к нарушению принципов React, связанных с неизменностью данных. Вместо этого всегда клонируйте массивы и объекты для изменения, используя ... оператор или функцию map.

  3. Проверка и валидация:
    При работе с индексами важно убедиться в корректности их значений, например, добавить проверку, что индекс в пределах массива.

  4. Закладка на будущее:
    При компоновке интерфейсов рекомендуется отделять логику от внешнего интерфейса. Это достигается через использование хуков и хелперов. Если ваш проект расширится, возможно, вы задумаетесь о более сложной системе состояния, как Redux, хотя чаще всего для небольших проектов это избыточно.

  5. Производительность:
    Обновление атрибутов блока каждый раз, когда изменяется один элемент, считается нормальной практикой, но может быть неоптимально в больших системах. В этом случае может быть полезен useMemo или useCallback, чтобы избежать ненужного повторного вычисления.

Заключение

Использование setAttributes — это стандартный и рекомендуемый способ обновления состояния блока в Gutenberg, который обеспечивает корректное обновление вашего UI без непосредственного вмешательства в DOM. Ваш метод удаления вполне адекватен, несмотря на его "громоздкость", но его можно оптимизировать для повышения читаемости и производительности. Очевидно, что глубоко понимая это, вы сможете создавать более модульные и легко поддерживаемые решения в контексте разработки для WordPress.

Оцените материал
Добавить комментарий

Капча загружается...