Работа с библиотекой Cleave.js почти всегда опирается на доступ к экземпляру маскировщика. Внутренний объект Cleave хранит состояние форматирования, правила обработки ввода и методы управления значением поля. Именно через него реализуется программное управление вводом, синхронизация с внешним состоянием и интеграция с фреймворками.
В большинстве случаев экземпляр создаётся через конструктор:
import Cleave from 'cleave.js';
const cleave = new Cleave('#input', {
numeral: true,
numeralThousandsGroupStyle: 'thousand'
});
Переменная cleave и есть реф на активный экземпляр.
Через неё выполняется весь дальнейший контроль поведения поля.
Реф выполняет функцию связующего слоя между DOM-элементом и логикой форматирования. Без него невозможно:
Важно учитывать, что Cleave не является декларативной библиотекой. Все изменения происходят через императивный API экземпляра.
Самый простой вариант — хранение результата конструктора:
let cleaveInstance = null;
function init() {
cleaveInstance = new Cleave('#phone', {
phone: true,
phoneRegionCode: 'US'
});
}
Такой подход используется в нативном JavaScript и при работе без фреймворков.
В архитектурах с модульностью экземпляр часто помещается в состояние модуля:
const formController = {
cleave: null,
init() {
this.cleave = new Cleave('#card', {
creditCard: true
});
}
};
Это позволяет централизованно управлять экземпляром и вызывать методы из разных частей системы.
В React интеграции используется механизм useRef,
поскольку прямой доступ к DOM и экземплярам должен быть стабилизирован
между рендерами.
import { useEffect, useRef } from 'react';
import Cleave from 'cleave.js';
function CardInput() {
const inputRef = useRef(null);
const cleaveRef = useRef(null);
useEffect(() => {
cleaveRef.current = new Cleave(inputRef.current, {
creditCard: true
});
return () => {
cleaveRef.current?.destroy();
};
}, []);
return <input ref={inputRef} />;
}
Ключевой момент: useRef используется не только для DOM,
но и для хранения экземпляра Cleave, чтобы избежать пересоздания при
рендерах.
Экземпляр предоставляет набор методов, позволяющих управлять состоянием ввода.
Устанавливает «сырое» значение без форматирования.
cleave.setRawValue('4111111111111111');
После вызова значение автоматически форматируется согласно конфигурации (например, как номер карты).
Возвращает значение без маски и форматирования.
const raw = cleave.getRawValue();
Используется при отправке формы, когда требуется чистое значение.
Возвращает текущее отображаемое значение с форматированием.
const formatted = cleave.getFormattedValue();
Полезно для логирования или отображения предпросмотра.
Изменяет регион для телефонной маски на лету.
cleave.setPhoneRegion('RU');
При изменении региона Cleave пересчитывает формат ввода и обновляет отображение.
Полностью уничтожает экземпляр и возвращает поле к обычному input.
cleave.destroy();
Этот метод критически важен при работе в SPA, где компоненты часто монтируются и размонтируются.
После вызова:
Иногда требуется прямой доступ к DOM-элементу, который управляется Cleave.
const input = cleave.element;
input.focus();
Свойство element хранит ссылку на исходный input. Через
него можно выполнять любые DOM-операции, не связанные с
форматированием.
При интеграции с UI-фреймворками часто возникает необходимость синхронизации внешнего состояния и Cleave-инстанса.
function updateValue(value) {
if (!cleaveInstance) return;
cleaveInstance.setRawValue(value);
}
Важно использовать именно setRawValue, а не прямое
изменение DOM, иначе форматирование может нарушиться.
В некоторых случаях требуется пересоздание экземпляра при изменении конфигурации.
function reinit(options) {
if (cleaveInstance) {
cleaveInstance.destroy();
}
cleaveInstance = new Cleave('#input', options);
}
Такой подход используется при динамическом изменении типа маски: например, переключение между телефоном и номером карты.
При наличии нескольких полей каждый экземпляр хранится отдельно:
const cleaves = {
phone: null,
card: null,
date: null
};
cleaves.phone = new Cleave('#phone', { phone: true });
cleaves.card = new Cleave('#card', { creditCard: true });
cleaves.date = new Cleave('#date', { date: true });
Это позволяет централизованно управлять всеми масками формы.
Экземпляр Cleave живёт независимо от DOM-рендера, поэтому важно контролировать его вручную:
Игнорирование destroy() приводит к утечкам памяти и
дублированию обработчиков событий.
new Cleave('#input', {...});
Без сохранения результата невозможно управлять экземпляром после создания.
input.value = '1234';
Такой подход обходит Cleave и нарушает форматирование. Корректный вариант:
cleave.setRawValue('1234');
Создание нового экземпляра поверх старого приводит к конфликту обработчиков:
cleave = new Cleave('#input', {...}); // без destroy — ошибка архитектуры
Реф Cleave-инстанса выступает как низкоуровневый контроллер ввода. Он находится ниже уровня бизнес-логики и выше DOM-слоя. Через него проходят все операции:
Такой слой часто становится частью формы-менеджера, где каждый input управляется отдельным инстансом с собственным жизненным циклом.