Мотивация:
На днях я обнаружил, что ищу информацию о том, как реализовать отзывчивый дизайн в реактивных компонентах, я не мог найти ничего чистого, ничего, что могло бы сделать ссылку на любой шаблон или рекомендуемый метод, поэтому я решил немного подумать об этой теме.
Как только я начал искать информацию об отзывчивом дизайне, использование медиа-запросов быстро придумывает, но обычно связано с окном устройства, в котором его рисуется, что, кажется, не вносит большого вносящего вклад для изолированных компонентов.
Создание компонента реагировать на изменения всего окна Размеры, похоже, не имеют смысла, компонент должен ответить на свои размеры, не должен ли это ??
Также верно, что некоторые инструменты CSS могут использоваться для управления расположением элементов в имеющемся пространстве, например, с Flexbox или CSS-сеткой Некоторые адаптивные поведения могут быть даны элементам. Но я не думаю, что это может добраться до того же уровня, что и используя медиа-запросы.
По этой причине я думал, что, возможно, используя ту же концепцию медиа-запросов, но ориентированных на компоненты, может быть хорошей идеей.
Что мы хотим достичь?
Что-то вроде этого…
Как это реализовать?
Как только я начал задаваться интересно, как я мог реализовать что-то вроде этого, появился Resizebserver, API браузера, который позволяет нам обнаружить изменения размера компонента и реагировать на это, поэтому кажется, что это может быть полезно для того, что я хочу сделать.
Другое, что нужно, – это обеспечить стандартный способ определить точки останова для элемента и способа обнаружения диапазона размеров компонента в любой момент времени, которые могут быть реализованы без особых трудностей.
Мой подход для этой задачи был:
- Сначала выберите структуру, чтобы установить, как следует определить точки останова для компонента.
- Из этих точек останова определите список размеров и генерируют класс CSS для каждого из них.
- Также потребуется определение размера компонента после каждого изменения, найдите, в каком диапазоне он включен и назначить соответствующий класс CSS.
Таким образом, он может иметь то же поведение, что и в случае медиа-запросов. Каждый раз, когда компонент изменяет свой диапазон, мы можем назначить класс CSS PropPer, а будут применяться необходимые стили.
Как вы можете видеть, идея проста, и это процедура. Я решил инкапсулировать логику в крючке, чтобы иметь возможность повторно повторно повторно повторно повторно использовать его, где это необходимо. https://www.npmjs.com/package/@jrx2-dev/use-responsive-class
Как работает этот крючок?
Крючок получает ссылку на контроль компонента, и необязательно использование точек останова. В случае не получающих точек останова, предопределенные будут использованы предопределенные.
Точки останова должны реализовать следующий интерфейс:
interface breakpointsInput {
readonly [key: string]: number;
}
Пример (по умолчанию точек останова):
const MEDIA_BREAKPOINTS: breakpointsInput = {
small: 420,
big: 768,
};
Диапазоны ширины (MediabreakPoints) будут созданы в соответствии с использованными точками останова (с их соответствующими образованными классами CSS).
Сгенерированные медиабректуры будут соответствовать следующему интерфейсу:
interface mediaBreakpoints {
class: string;
from: number;
toUnder: number;
}
И…
createMediaBreakpoints(MEDIA_BREAKPOINTS);
… должен вернуться:
[
{
class: "to-small",
from: 0,
toUnder: 420,
},
{
class: "from-small-to-under-big",
from: 420,
toUnder: 768,
},
{
class: "from-big",
from: 768,
toUnder: Infinity,
},
];
Всякий раз, когда обнаружено изменение размера компонента, будет выпущен метод getCurrentsizeclass, а класс CSS, соответствующий данному диапазону ширины.
getCurrentSizeClass(elementWidth, mediaBreakpoints)
Как использовать этот крюк:
npm i @jrx2-dev/use-responsive-class
import { useResponsiveClass } from '@jrx2-dev/use-responsive-class';
/*
const elementBreakpoints: breakpointsInput = {
small: 420,
big: 768,
};
*/
const elRef = createRef();
const [responsiveClass] = useResponsiveClass(elRef);
// const [responsiveClass] = useResponsiveClass(elRef, elementBreakpoints);
return (
Some content
);
Стили должны быть что-то вроде этого (модули CSS используются в демонстрационном проекте):
.root {
&.to-small {
background-color: green;
}
&.from-small-to-under-big {
background-color: yellow;
}
&.from-big {
background-color: red;
}
}
Демо:
Я использовал этот пользовательский крюк в библиотеке компонентов, которую я сделал для использования в личных демонстрационных проектах. https://www.npmjs.com/package/@jrx2-dev/react-components
Вы можете увидеть эту технику на работе с примером компонента в рассказе книги проекта. https://jrx2-dev.github.io/react-components
Примечание:
Я должен сказать, что я немного отвлекал добавление анимации между изменением компонентов компонента, логика инкапсулирована в крючке UseFadeonsizeChange, я думаю, что необходимо было сделать переход между макетами немного более жидкости.
Вывод:
Этот эксперимент послужил мне доказательством концепции для разработки системы, которая позволяет конструировать действительно отзывчивые компоненты в реакции.
Очевидно, что код может быть улучшен, любые комментарии или предложения приветствуются. Идея этой статьи была в основном скрытым вопросом … Как бы вы это сделали?:)
Что касается PEFORMANCE, третий сторонний крючок (@ React-Club/Resize-Observer), оптимизированный для реализации Resizebserver, используется и, похоже, дает хорошие результаты.
То, что я заинтересован в выделении здесь, не так много самой реализации, но используемая концепция, я хотел бы услышать мнения и предложения о том, как вы справляетесь с этим вопросом.
Оригинал: “https://dev.to/jrx2/responsive-design-in-react-components-7d1”