Создайте приложение React используя Styled Components

Published on
Authors

Когда вы создаете приложения React, в какой-то момент вам нужно принять решение о том, как организовать свои стили CSS. Для более крупных приложений вам придется разбить таблицы стилей на модули. Такие инструменты, как Sass и Less, позволяют разделить стили на отдельные файлы и предоставляют множество других функций, которые делают написание файлов CSS более продуктивным. Но некоторые проблемы остаются. Инструменты отделяют ваши стили от ваших компонентов, и поддерживать стили в актуальном состоянии с остальной частью вашего кода может быть сложно. Трудно понять, использует ли большое приложение, которое разрабатывалось и модифицировалось в течение нескольких лет, определенный класс CSS. Также нелегко убедиться, что изменение стиля в одной части вашего приложения не повлияет на внешний вид какого-либо другого несвязанного компонента.

Styled Components спешат на помощь

Решением этих проблем является концепция, известная как стили с ограниченными областями видимости. Здесь вы пишете стили CSS, которые применяются только в четко определенном контексте. Например, вы можете написать стили, которые применяются только к одному компоненту React. Библиотека стилизованных компонентов реализует эту концепцию. Вы можете создавать стили CSS непосредственно в коде JavaScript и прикреплять их к тегу HTML или существующему компоненту, чтобы создать новый компонент со стилями. Стили ограничены и применяются только к этому компоненту. Это дает ряд преимуществ.

  1. Вы определяете компоненты и стили в одном месте. Если вы удаляете компонент из приложения, вы одновременно удаляете и стили.
  2. Стили ограничены. Они применяются только к одному компоненту, хотя вы также можете применять стили к дочерним компонентам.
  3. Стили динамичны. Вы можете использовать любое выражение JavaScript в своих таблицах стилей. Вы также можете определять стили в зависимости от свойств компонента.

В этом руководстве я покажу вам, как использовать стилизованные компоненты в вашем приложении React, создав простое приложение-календарь.

Create a React App

Я предполагаю, что у вас есть некоторые базовые знания о React и что в вашей системе установлена ​​последняя версия Node. Вероятно, наиболее известным из них является диспетчер пакетов npm. Менее известна команда npx, которая позволяет запускать команды, установленные в вашем локальном репозитории. Если он не может найти команду, npx автоматически установит команды перед ее выполнением.

Вы всегда должны использовать более свежие версии интерфейса командной строки React с npx. Это гарантирует, что вы всегда используете самую последнюю версию. Это гарантирует, что вы всегда используете самую последнюю версию. Чтобы создать новое приложение React, откройте терминал, перейдите в каталог по вашему выбору и выполните следующую команду.

npx create-react-app react-styled-calendar

Это создаст новую папку с именем response-styled-calendar и инициализирует приложение React внутри нее. Для создания календаря вы будете использовать пакет moment. Это мощный пакет для работы со временем и датой. Перейдите во вновь созданную папку проекта и установите пакет moment.

cd react-styled-calendar
npm install moment

Теперь откройте ваш любимый редактор, создайте файл src/Calendar.js и создайте новый компонент календаря, вставив в файл приведенный ниже код.

import React, { Component } from 'react';
import moment from 'moment';

export class Calendar extends Component {

  constructor(props) {
    super(props);
    this.state = {
      date: moment(),
    }
  }
}

Здесь конструктор просто инициализирует состояние компонента текущей датой. Компоненту нужен метод, который создает все дни текущего месяца. А пока вы поместите каждый день месяца в элемент div. Добавьте следующий метод в компонент Calendar

createDaysOfMonth(refDate) {
  const date = moment(refDate).endOf('month');
  const lastDate = date.date();
  const firstWeekday = date.startOf('month').day();

  const calendarDays = [];

  const today = moment();

  for (let w=0; w<firstWeekday; w++) {
    calendarDays.push(<div key={Math.random()}/>); // empty days
  }

  for (let d=1; d<lastDate; d++) {
    calendarDays.push(<div key={d} today={date.date(d).isSame(today, 'day')}>{d}</div>);
  }

  while (calendarDays.length % 7 !== 0) {
    calendarDays.push(<div key={Math.random()}/>);
  }

  return calendarDays;
}

Первые три строки показывают, сколько дней в текущем месяце и с какого дня недели начинаются месяцы. В макете месяца в календаре обычно есть несколько пустых полей в начале и в конце, чтобы учесть тот факт, что месяц не всегда начинается в один и тот же день недели. Код добавляет это заполнение, используя первый цикл for и последний цикл while. Затем средний цикл for добавляет все дни месяца, создавая блоки div, содержащие номер даты.

Теперь вам нужны два метода для обновления состояния компонентов с помощью навигации по месяцам. Добавьте в компонент Calendar следующие два метода.

prevMonth() {
  this.setState({date: this.state.date.subtract(1, 'month')})
}

nextMonth() {
  this.setState({date: this.state.date.add(1, 'month')})
}

Теперь вы готовы визуализировать календарь. Метод render() показывает текущий месяц и год, две кнопки для навигации, а затем вид месяца. Вставьте следующий код в компонент Calendar.

render() {
  return <div>
    <h2>{this.state.date.format('MMMM YYYY')}</h2>
    <div>
      <button onClick={this.prevMonth.bind(this)}>&lt;</button>
      <button onClick={this.nextMonth.bind(this)}>&gt;</button>
    </div>
    <div>
      <div>Sunday</div>
      <div>Monday</div>
      <div>Tuesday</div>
      <div>Wednesday</div>
      <div>Thursday</div>
      <div>Friday</div>
      <div>Saturday</div>
      {this.createDaysOfMonth(this.state.date)}
    </div>
  </div>;
}

Чтобы компонент отображался в вашем приложении, вам необходимо добавить его в основной компонент приложения. Откройте src/App.js и замените его содержимое приведенным ниже кодом.

import React from 'react';
import { Calendar } from './Calendar';
import './App.css';

function App() {
  return (
    <div className="App">
      <Calendar/>
    </div>
  );
}

export default App;

Теперь у вас есть полностью функционирующий календарь, который вы можете протестировать, выполнив следующую команду в терминале.

npm start

Откройте свой браузер по адресу http: //localhost:3000, и вы увидите свой календарь. Нажимайте кнопки со стрелками, чтобы просматривать месяцы. Конечно, в календаре еще нет стиля, поэтому все дни отображаются в одном длинном столбце.


Добавьте аутентификацию в свое приложение React

С Okta вы можете быстро настроить безопасную аутентификацию и контролировать, какие пользователи могут получить доступ к вашему приложению. В этом разделе я покажу вам, как добавить аутентификацию в ваше приложение React. Во-первых, вам нужно будет зарегистрировать бесплатную учетную запись разработчика в Okta.

Откройте браузер, перейдите на https://developer.okta.com, перейдите по ссылке для входа и заполните форму, которая появится рядом. После регистрации вы попадете в личный кабинет Okta.

Выберите Applications в верхнем меню и создайте свое первое приложение, нажав кнопку Add Application. На следующем экране выберите Single-Page App и нажмите Next.

Вы увидите экран с настройками. Убедитесь, что для порта установлено значение 3000, а для URL-адреса возврата задано значение http://localhost:3000/callback. Это порт, который ваше приложение React использует для запуска сервера разработки. Когда вы закончите, нажмите Done.

На открывшемся экране будет указан идентификатор клиента, который нужно будет скопировать и вставить в свое приложение, выполнив следующие действия.

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

npm install @okta/okta-react @okta/okta-auth-js react-router-dom

Теперь откройте src/App.js и обновите его содержимое, чтобы оно соответствовало следующему коду.

import React from 'react';
import { Calendar } from './Calendar';
import './App.css';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { LoginCallback, SecureRoute, Security } from '@okta/okta-react';

function App() {
  return (
      <Router>
        <Security issuer='https://{YourOktaDomain}/oauth2/default'
                  clientId='{ClientId}'
                  redirectUri={window.location.origin + '/callback'}
               pkce={true}>
          <SecureRoute path='/' exact={true} component={Calendar}/>
          <Route path='/callback' component={LoginCallback}/>
        </Security>
      </Router>
  );
}

export default App;

В приведенном выше коде {ClientId} - это идентификатор клиента, который вы получили из панели управления Okta, а {YourOktaDomain} - ваш домен Okta. Вот и все! Вы настроили аутентификацию и защитили приложение-календарь от несанкционированного доступа. Больше ничего.

Добавьте Styled Components в ваше приложение React

Теперь пришло время добавить стиль вашему приложению. В этом разделе я покажу вам, как установить и использовать Styled Components в React. Сначала установите в проект пакет styled-components. Откройте свой терминал в корневой папке проекта и выполните следующую команду.

npm install styled-components

Теперь создайте новый файл src/CalendarComponents.js и создайте базовые компоненты, которые будут служить элементами контейнера для вашего календаря.

import styled from 'styled-components';

export const CalendarWrapper = styled.div`
	display: flex;
	flex-direction: column;
	align-items: center;
`;

export const CalendarContainer = styled.div`
	width: 100%;
	max-width: 800px;
	display: flex;
	flex-wrap: wrap;
`;

Механизм литерала шаблона JavaScript создает стилизованные компоненты. Обратите внимание на обратные галочки, окружающие строки CSS в приведенном выше коде. Добавляя к строке шаблона префикс одного из тегов, предоставляемых styled-components, вы создаете новый компонент. Код применяет CSS к этому компоненту, не влияя на другие стили или макеты вашего приложения. На следующей кнопке вы можете увидеть, как вы можете вкладывать стили и использовать амперсанд & почти так же, как вы бы использовали его в SASS.

export const PagingButton = styled.button`
  display: inline-block;
  background-color: #3f51b5;
  color: #ffffff;
  font-size: 24px;
  border: none;
  border-radius: 4px;
  margin: 12px;
  cursor: pointer;
  &:hover {
    background-color: #334296;
  }
`;

Вы также можете использовать выражения и сделать стиль зависимым от свойств, переданных компоненту. Следующий код стилизует поля дня календаря.

export const Day = styled.div`
  box-sizing: border-box;
  font-size: 24px;
  width: ${ 100 / 7 }%;
  padding: 8px;
  background-color: ${props => props.today ? '#3f51b5' : '#f0f0f0'};
  color: ${props => props.today ? '#ffffff' : '#000000'};
  border: 2px solid #ffffff;
  height: 64px;
`;

Вы могли заметить, что компонент Day проверяет, истинно ли значение props.today. Если это так, он назначает другой цвет фона и цвет текста. Наконец, создайте новый компонент, добавив стиль к существующему компоненту. Вызовите styled () с конструктором компонента.

export const DayHeader = styled(Day)`
  text-align: center;
  font-size: 16px;
  padding-top: 12px;
  height: 48px;
`;

Здесь я пропустил день Styled Componen, но вы могли бы передать любой существующий компонент React, чтобы добавить к нему стиль.

Добавьте константы PagingButton, Day и DayHeader в src/CalendarComponent.js.

Пришло время использовать все созданные вами компоненты. Откройте src/Calendar.js и в верхней части файла импортируйте компоненты.

import {
  CalendarWrapper,
  CalendarContainer,
  PagingButton,
  Day,
  DayHeader
} from './CalendarComponents'

Внутри createDaysOfMonth() замените все вхождения тега div на тег Day. Затем обновите метод render(), чтобы он выглядел следующим образом.

render() {
  return <CalendarWrapper>
    <h2>{this.state.date.format('MMMM YYYY')}</h2>
    <div>
      <PagingButton onClick={this.prevMonth.bind(this)}>&lt;</PagingButton>
      <PagingButton onClick={this.nextMonth.bind(this)}>&gt;</PagingButton>
    </div>
    <CalendarContainer>
      <DayHeader>Sunday</DayHeader>
      <DayHeader>Monday</DayHeader>
      <DayHeader>Tuesday</DayHeader>
      <DayHeader>Wednesday</DayHeader>
      <DayHeader>Thursday</DayHeader>
      <DayHeader>Friday</DayHeader>
      <DayHeader>Saturday</DayHeader>
      {this.createDaysOfMonth(this.state.date)}
    </CalendarContainer>
  </CalendarWrapper>;
}

Обратите внимание, как вы обновили только теги, чтобы использовать новые стилизованные компоненты. Больше ничего не изменилось. Протестируйте свое приложение еще раз.

npm start

Снова откройте браузер по адресу http://localhost:3000, чтобы увидеть, как теперь выглядит ваш календарь. После входа в систему с учетными данными Okta вы должны увидеть что-то вроде изображения ниже.

Поздравляю! Вы узнали основы того, как создавать стилизованные компоненты и использовать их в своих приложениях React