Steroids React Boilerplate туториал

В этой статье представлен пример создания приложения с использованием Steroids React Boilerplate. Приложение состоит из двух страниц - Профиль и Настройки. В профиле расположена карточка с данными о пользователе, которого можно создать в форме на странице настроек.

Итак, приступим к созданию нашего приложения. Перед началом работы у нас должен быть склонированый репозиторий Steroids React Boilerplate. Проект бойлерплейта запущен в режиме разработки. Подробнее о том, как это сделать, можно прочитать в статье Быстрый старт.

Для начала добавим в дерево роутов, которое находится в файле routes/index.ts, страницу профиля и страницу настроек. Более подробно про дерево роутов вы можете прочитать в статье про Роутинг.

После добавления соответсвующих страниц, получилось следующее дерево роутов:

import {IRouteItem} from '@steroidsjs/core/ui/nav/Router/Router';
import IndexPage from './IndexPage';
import ProfileGeneral from './ProfileGeneral';
import ProfileSettings from './ProfileSettings';

export const ROUTE_ROOT = 'root';
export const ROUTE_PROFILE_GENERAL = 'general';
export const ROUTE_PROFILE_SETTINGS = 'settings';

const roles = [null];

export default {
    id: ROUTE_ROOT,
    exact: true,
    path: '/',
    redirectTo: ROUTE_PROFILE_SETTINGS,
    label: __('Главная страница'),
    component: IndexPage,
    roles,
    items: {
        [ROUTE_PROFILE_GENERAL]: {
            label: __('Страница профиля'),
            path: '/general',
            component: ProfileGeneral,
        },
        [ROUTE_PROFILE_SETTINGS]: {
            label: __('Настройки'),
            path: '/settings',
            component: ProfileSettings,
            isNavVisible: false,
        },
    },
} as IRouteItem;

Далее нужно добавить проверку, находимся ли мы на странице настроек.

Для этого, внесем изменения в файл src/shared/Layout:

// 'shared/Layout/Layout.tsx'
import {useBem, useSelector} from '@steroidsjs/core/hooks';
import {Notifications} from '@steroidsjs/core/ui/layout';
import Header from '@steroidsjs/core/ui/layout/Header';
import Portal from '@steroidsjs/core/ui/layout/Portal';
import ModalPortal from '@steroidsjs/core/ui/modal/ModalPortal';
import {getRoute} from '@steroidsjs/core/reducers/router';

import {ROUTE_ROOT} from '../../routes';
import './Layout.scss';

export default function Layout(props: React.PropsWithChildren<any>) {
    const bem = useBem('Layout');

    const isSettingsRoute = useSelector(getRouteId) === ROUTE_PROFILE_SETTINGS;

    if (isSettingsRoute) {
        return (
            <div className={bem.block('settings')}>
                <Notifications />
                <ModalPortal />
                <main role="main">
                    {props.children}
                </main>
            </div>
        );
    }

    return (
        <div className={bem.block()}>
            <Header
                logo={{
                    title: 'Steroids Demo',
                }}
                nav={{
                    items: ROUTE_ROOT,
                }}
            />
            <div className={bem.element('content')}>
                <Notifications />
                {props.children}
                <ModalPortal />
                {
                    process.env.IS_SSR
                        ? null
                        : <Portal />
                }
            </div>
        </div>
    );
}

Теперь создадим страницу профиля и страницу настроек. Все страницы располагаются в папке src/routes/. Каждая страница или компонент выделяются в отдельную папку и должны содержать в себе два файла — tsx и scss, а также файл index.ts для более короткого импорта созданных компонентов. Подробнее о файловой структуре можно прочитать в статье "Архитектура проекта" в разделе "React компоненты".

На странице профиля мы будем проверять, есть ли заполненные данные профиля в redux хранилище, и если данные есть — отображать их с помощью компонента <Card/>. Если данных нет, то пользователю предлагается создать профиль.

Пример:

// 'routes/ProfilePage/ProfilePage.tsx'
import useBem from '@steroidsjs/core/hooks/useBem';
import {Card} from '@steroidsjs/core/ui/content';
import {useDispatch, useSelector} from '@steroidsjs/core/hooks';
import {goToRoute} from '@steroidsjs/core/actions/router';
import {formSelector} from '@steroidsjs/core/reducers/form';

import {FORM_ID} from '../ProfileSettings/ProfileSettings';
import {ROUTE_PROFILE_SETTINGS} from '../index';
import './ProfileGeneral.scss';

export default function ProfilePage() {
    const bem = useBem('ProfilePage');
    const dispatch = useDispatch();

    const formValues = useSelector(state => formSelector(state, FORM_ID, ({values}) => values));

    return (
        <div className={bem.block()}>
            {formValues ? (
                    <Card
                        className='card'
                        header={{
                            avatar: {
                                src: 'https://i.ibb.co/T4j2NMQ/20230325210515-1.jpg',
                                status: true,
                            },
                            head: formValues.name,
                            subhead: formValues.surname,
                        }}
                        title={formValues?.about && __('О себе')}
                        description={formValues?.about ?? null}
                        buttons={[
                            {
                                label: __('Редактировать'),
                                onClick: () => {
                                    dispatch(goToRoute(ROUTE_PROFILE_SETTINGS));
                                },
                            },
                        ]}
                    />
                )
                : (
                    <div className={bem.element('empty')}>
                        <Button
                            label={__('Создать профиль')}
                            onClick={() => dispatch(goToRoute(ROUTE_PROFILE_SETTINGS))}
                        />
                    </div>
                )}
        </div>
    );
}

Для создания профиля нам понадобится соответсвующая страница.

Создадим страницу SettingsPage и добавим на нее форму для создания и редактирования профиля:

// 'routes/SettingsPage/SettingsPage.tsx'
import useBem from '@steroidsjs/core/hooks/useBem';
import {useDispatch} from '@steroidsjs/core/hooks';
import {Button, Form, InputField, TextField} from '@steroidsjs/core/ui/form';
import {goToRoute} from '@steroidsjs/core/actions/router';

import {ROUTE_PROFILE_GENERAL} from '../index';
import './SettingsPage.scss';

export const FORM_ID = 'ProfileSettings';

export default function SettingsPage() {
    const bem = useBem('SettingsPage');
    const dispatch = useDispatch();

    return (
        <div className={bem.block()}>
            <Form
                formId={FORM_ID}
                useRedux
                className={bem.element('form')}
                onSubmit={() => dispatch(goToRoute(ROUTE_PROFILE_GENERAL))}
            >
                <h2 className={bem.element('title')}>{__('Создать профиль')}</h2>
                <InputField
                    attribute='name'
                    label={__('Имя')}
                    required
                />
                <InputField
                    attribute='surname'
                    label={__('Фамилия')}
                    required
                />
                <TextField
                    attribute='about'
                    label={__('О себе')}
                    required
                />
                <Button
                    type='submit'
                    label='Сохранить'
                />
            </Form>
        </div>
    );
}

При сабмите происходит переход на страницу профиля, а поля формы сохранятся в redux хранилище благодаря флагу useRedux.

Вот и все! Спасибо, что попробовали Steroids React Boilerplate. Мы надеемся, что это руководство поможет вам начать разработку вашего веб-приложения с использованием фреймворка Steroids.