Кастомизация приложения
В файле Application.tsx можно кастомизировать приложение, добавив кастомные reducers, components, icons.
Вот так выглядит файл в boilerplate:
import useApplication from '@steroidsjs/core/hooks/useApplication';
import HttpComponent from '@steroidsjs/core/components/HttpComponent';
import LocaleComponent from '@steroidsjs/core/components/LocaleComponent';
import customIcons from 'icons/index';
import 'style/index.scss';
export default function Application() {
const {renderApplication} = useApplication({
reducers: require('@steroidsjs/core/reducers').default,
routes: () => require('routes').default,
layoutView: () => require('shared/Layout').default,
screen: {},
components: {
locale: LocaleComponent,
http: HttpComponent,
},
onInit: ({ui}) => {
ui.addViews(require('./ui/bootstrap').default);
ui.addFields(require('@steroidsjs/core/ui/form').default);
ui.addFormatters(require('@steroidsjs/core/ui/format').default);
ui.addIcons(require('@steroidsjs/bootstrap/icons/index').default(customIcons));
},
});
return renderApplication();
}Добавление кастомных reducers
Чтобы добавить reducer в приложение нужно выполнить несколько шагов:
1. Создать папку src/reducers/.
2. Создать в ней файл index.ts и добавить в него export функции, которая комбинирует все reducers из Steroids.
Пример кода:
import steroidsReducers from '@steroidsjs/core/reducers';
export default asyncReducers => steroidsReducers({
...asyncReducers,
});3. Создать в папке src/reducers/ необходимые кастомные reducers (каждый в отдельном файле) и добавить их в объект с reducers, который передается первым аргументов в функцию combineReducers.
4. В файле Application.tsx изменить путь до файла с reducers с @steroidsjs/core/reducers на ./reducers.
Добавление кастомных иконок
По умолчанию, Steroids содержит набор иконок для старта. Список предоставляемых иконок можно найти в репозитории react-bootstrap в папке src/icons/svgs.
Для добавления пользовательских иконок нужно выполнить несколько шагов:
1. Добавить иконку в проект, как правило в папку src/icons/svgs.
2. Перейти в файл src/icons/index.ts, который изначально пустой:
export const icons = {
// сюда можно добавить иконки
};3. Добавить иконку в конфигурационный объект нужно следующим образом:
export const icons = {
kozhinDev: require('./svgs/kozhinDev.svg'),
};В данном примере kozhinDev это ключ — название для использования иконки в приложении, а require('./svgs/kozhinDev.svg') значение — путь до файла иконки.
4. Затем, в файле Application.tsx нужно подключить кастомные иконки:
{/* ... */}
import customIcons from 'icons/index'; // импортируем наш объект с иконками
export default function Application() {
const {renderApplication} = useApplication({
/* ... */
onInit: ({ui}) => {
/* Подключаем кастомные иконки, передавая их в качестве аргумента */
ui.addIcons(require('@steroidsjs/bootstrap/icons/index').default(customIcons));
},
});
return renderApplication();
}5. Теперь, добавленные иконки можно использовать в приложении, обращаясь к ним по названию:
import Icon from '@steroidsjs/core/ui/content/Icon';
export default () => (
<Icon name='kozhinDev' />
);Добавление кастомных компонентов
В Steroids существует набор компонентов для работы с Redux, с запросами на бэкенд, локализацией и т. д.
Кроме использования уже готовых компонентов, вы также можете:
- Расширить функционал уже существующего компонента, добавив бизнес-логику для конкретного проекта.
- Добавить собственный компонент и передать ему необходимые пропсы.
Далее рассмотрим отдельно каждый способ.
1. Расширение функционала уже существующего компонента
Для примера расширим функционал компонента HttpComponent. Допустим, мы хотим, чтобы при отправке запроса на бекенд добавлялся заголовок Accept-Language для локализации ответа от сервера.
Для начала создаём компонент HttpComponent в папке src/components/. Этот компонент будет расширять встроенный в Steroids компонент, добавляя в метод _send заголовок Accept-Language:
import SteroidsHttpComponent from '@steroidsjs/core/components/HttpComponent';
export default class HttpComponent extends SteroidsHttpComponent {
_send(method: string, config?: Record<string, any>, options?: Record<string, any>) {
const configWithLanguage = {
headers: {
'Accept-Language': this._components.locale.language,
},
...config,
};
return super._send(method, configWithLanguage, options);
}
}Далее подключаем расширенный компонент в конфигурацию Application.tsx:
import useApplication from '@steroidsjs/core/hooks/useApplication';
import LocaleComponent from '@steroidsjs/core/components/LocaleComponent';
import HttpComponent from './components/HttpComponent'; // импортируем компонент
import 'style/index.scss';
export default function Application() {
const {renderApplication} = useApplication({
reducers: require('@steroidsjs/core/reducers').default,
routes: () => require('routes').default,
layoutView: () => require('shared/Layout').default,
screen: {},
components: {
locale: {
className: LocaleComponent,
},
http: {
className: HttpComponent, // подключаем кастомный компонент
apiUrl: process.env.APP_BACKEND_URL, // дополнительно указываем URL адрес
// здесь можно передать необходимые пропсы для компонента
},
},
onInit: ({ui}) => {
ui.addViews(require('./ui/bootstrap').default);
ui.addFields(require('@steroidsjs/core/ui/form').default);
ui.addFormatters(require('@steroidsjs/core/ui/format').default);
ui.addIcons(require('@steroidsjs/bootstrap/icons/index').default(customIcons));
},
});
return renderApplication();
}Примечание: если для конфигурации компонента не нужно пробрасывать дополнительные пропсы, можно использовать краткую запись.
Пример кода:
import useApplication from '@steroidsjs/core/hooks/useApplication';
import HttpComponent from './components/HttpComponent';
export default function Application() {
const {renderApplication} = useApplication({
components: {
http: HttpComponent,
},
});
return renderApplication();
}После конфигурации кастомного компонента мы можем получить к нему доступ с помощью хука useComponents, указав его название (так же, как при использовании дефолтного компонента из Steroids).
Ниже представлен пример использования компонента http для получения списка комментариев:
import {useEffect, useState} from 'react';
import {useComponents} from '@steroidsjs/core/hooks';
import Comment from './views/Comment';
import API_METHODS from '../../config/api';
import './Comments.scss';
interface ICommentsProps {
userId: number;
}
export default function Comments(props: ICommentsProps) {
const [comments, setComments] = useState([]);
const {http} = useComponents();
useEffect(() => {
http.get(API_METHODS.COMMENTS, {userId: props.userId})
.then((response) => setComments(response?.items));
}, [http, props.userId]);
return (
<div className'Comments'>
{
comments.map(comment => (
<Comment
key={comment.id}
text={comment.text}
/>
))
}
</div>
);
}2. Добавление собственного компонента
Помимо расширения функционала уже существующих компонентов, мы можем добавить собственный.
Для этого создаём кастомный компонент в папке src/components/, например ConverterComponent для конвертации валют из рублей в доллары:
export default class ConverterComponent {
rub: number;
course: number;
constructor(components, config: any = {}) {
this.rub = config.initialRubValue;
this.course = config.course;
}
rubToUsd(rub: number) {
return Number(((rub || this.rub) / this.course).toFixed(2));
}
}Подключаем ConverterComponent в конфигурацию приложения в Application.tsx, указав в качестве названия ключ converter и передав необходимые для конструктора аргументы:
import useApplication from '@steroidsjs/core/hooks/useApplication';
import Converter from './components/Converter';
import 'style/index.scss';
export default function Application() {
const {renderApplication} = useApplication({
reducers: require('@steroidsjs/core/reducers').default,
routes: () => require('routes').default,
layoutView: () => require('shared/Layout').default,
screen: {},
components: {
converter: {
className: Converter,
initialRubValue: 100,
course: 89,
},
},
onInit: ({ui}) => {
ui.addViews(require('./ui/bootstrap').default);
ui.addFields(require('@steroidsjs/core/ui/form').default);
ui.addFormatters(require('@steroidsjs/core/ui/format').default);
ui.addIcons(require('@steroidsjs/bootstrap/icons/index').default(customIcons));
},
});
return renderApplication();
}Ниже представлен пример использования компонента для конвертации валюты:
import {useEffect} from 'react';
import {useComponents, useDispatch, useSelector} from '@steroidsjs/core/hooks';
import {formChange} from '@steroidsjs/core/actions/form';
import {formSelector} from '@steroidsjs/core/reducers/form';
import {Form, NumberField} from '@steroidsjs/core/ui/form';
const FORM_ID = 'ConverterForm';
export default function ConverterForm() {
const dispatch = useDispatch();
const {converter} = useComponents();
const formValues = useSelector(state => formSelector(state, FORM_ID, ({values}) => values));
useEffect(() => {
const usd = converter.rubToUsd(Number(formValues?.rub));
dispatch(formChange(FORM_ID, 'usd', usd));
}, [converter, dispatch, formValues?.rub]);
return (
<Form
formId={FORM_ID}
useRedux
initialValues={{
rub: converter.rub,
}}
>
<NumberField
attribute='rub'
label='Сумма в рублях'
/>
<NumberField
attribute='usd'
label='Сумма в долларах'
disabled
/>
</Form>
);
}