Translate

Поиск по этому блогу

пятница, 11 мая 2018 г.

React.js (5) Оформление. React + CSS

Пришло время сделать наше приложение более привлекательным. Для этого давайте научимся работать со стилями в React.js



Все статьи по React.js



Для того, чтобы стилизовать React.js приложение существует огромное количество подходов, библиотек, разнообразных стилизованных компонентов. Мы возьмем самый популярный фреймворк - Bootstrap. Даже когда вы принимаете решение использовать Bootstrap, вы можете легко найти в Гугл множество библиотек, которые интегрировали в себя Bootstrap и дают вам возможность использовать уже готовые стилизованные компоненты. Вы можете выбрать для себя любую из них. Этих библиотек огромное количество.

Мы пойдем классическим путем и будем использовать чистый (классический) css от Bootstrap.

Подключение Bootstrap.


Для этого идем в консоль и устанавливаем с помощью npm сам bootstrap


   npm install bootstrap



npm - установит нам библиотеку и теперь мы сможем подключать стили. Для того, чтобы не тянуть стили руками в какой-либо html файл, мы можем подключать в наш проект css стили, как модули.

Это нам позволит сделать webpack, у которого для этого есть специальные возможности (модули), которые позволят подключать стили css в наш проект.

Для этого достаточно в файле App.js написать import и какой именно css модуль мы хотим подключить.

В нашем случае это 'bootstrap'. Обратите внимание, что подключаем без всяких слешей, потому что webpack и так поймет, что этот модуль стоит искать в папке -> node_modules. Указываем путь к файлу bootstrap.css.



Подключать файл bootstrap.min.css не имеет смысла, поскольку перед продакшн вы будете все равно минимизировать файлы с помощью webpack.

App.js

  import React from 'react'
  import ArticleList from './ArticleList'
  import articles from '../fixtures.js'
  import 'bootstrap/dist/css/bootstrap.css'

  function App() {
    return (
      <div>
          <h1>App Name</h1>
          <ArticleList articles={articles}/>
      </div>
    );
  }

  export default App



Теперь мы можем использовать bootstrap в нашем проекте.

Для того, чтобы дать класс какому-либо элементу нам достаточно написать className = "имя класса"

Например, пометить весь код в контейнер - в файле App.js первому тегу div добавили -


<div className="container" >



Убедиться, что все работает, вы можете открыв браузер и "исследовав элемент"



Класс добавился. И стили bootstrap прменились к нашим элементам.

Теперь давайте оформим каждый элемент.

Завернем наш header в div классом jumbotron, а самому заголовку дадим класс display-3


  import React from 'react'
  import ArticleList from './ArticleList'
  import articles from '../fixtures.js'
  import 'bootstrap/dist/css/bootstrap.css'

  function App() {
    return (
      <div className="container">
        <div className="jumbotron">
          <h1 className="display-3">App Name</h1>
        </div>  
          <ArticleList articles={articles}/>
      </div>
    );
  }

  export default App


Результат:



Теперь, перейдет к оформлению статей.

В файле Article.js мы добавим стили сразу на всю статью в className="card".

Заголовок поместим в header - div className="card-header", а сам текст статьи и дату в отдельный div className="card-header". Тело статьи в div className="card-body",

Article.js

import React, {Component} from 'react'

  class Article extends Component {
        state = {
          isOpen: true
      }

    render() {
        const {article} = this.props
        const body = this.state.isOpen && <section>{ article.text }</section> 
      return(
        <div className="card">
          <div className="card-header">
            <h2>
                { article.title }
                <button onClick={this.handleClick}>
                    {this.state.isOpen ? 'close' : 'open'}
                </button>
            </h2>
          </div>
          <div className="card-body"> 
               { body }
                <h3>
                   "creation date : "{ (new Date(article.date)).toDateString()}
                </h3>
          </div>
        </div>
      );
    }
    handleClick = () =>{
      console.log('---', 'clicked')
      this.setState({
        isOpen: !this.state.isOpen
      })
    }
  }

  export default Article



Посмотрим:



Немного изменим тело самой статьи и кнопку.

В файле Article.js
  import React, {Component} from 'react'

class Article extends Component {
      state = {
        isOpen: true
    }

  render() {
      const {article} = this.props
      const body = this.state.isOpen && <section className="card-text">{ article.text }</section> 
    return(
      <div className="card">
        <div className="card-header">
          <h2>
              { article.title }
              <button onClick={this.handleClick} className="btn btn-primary btn-lg float-right">
                  {this.state.isOpen ? 'close' : 'open'}
              </button>
          </h2>
        </div>
<div className="card-body"> <h6 className="card-subtitle text-muted"> "creation date : "{ (new Date(article.date)).toDateString()} </h6> { body } </div>
</div> ); } handleClick = () =>{ console.log('---', 'clicked') this.setState({ isOpen: !this.state.isOpen }) } } export default Article


Результат:



Делаем статью на пол экрана и работаем с инлайновыми стилями.


Для того. чтобы дать инлайновый стиль какому-либо элементу, достаточно прописать property style и в двойных фигурных скобках прописать свойство и значение.

Никакой магии в этом нет. Просто одни фигурные скобки говорят о том, что мы используем javascript переменную (выражение, или что-то еще), а вторые скобки говорят, что внутри обычная литеральная нотация.

Например так: <div className="card" style={{width:'50%'}}>

В принципе, мы могли бы вынести это таким вот образом -

const style = {width: '50%'}

а уже в самом теге оставить только <div className="card" style={style}>

Можно писать и так и так.



import React, {Component} from 'react'

  class Article extends Component {
        state = {
          isOpen: true
      }

    render() {
        const {article} = this.props
        const style = {width:'50%'}
        const body = this.state.isOpen && <section className="card-text">{ article.text }</section> 
      return(
        <div className="card" style={style}>
          <div className="card-header">
            <h2>
                { article.title }
                <button onClick={this.handleClick} className="btn btn-primary btn-lg float-right">
                    {this.state.isOpen ? 'close' : 'open'}
                </button>
            </h2>
          </div>
          <div className="card-body"> 
                <h6 className="card-subtitle text-muted">
                   "creation date : "{ (new Date(article.date)).toDateString()}
                </h6>
                { body }
          </div>
        </div>
      );
    }
    handleClick = () =>{
      console.log('---', 'clicked')
      this.setState({
        isOpen: !this.state.isOpen
      })
    }
  }

  export default Article




То, что получилось:



Для того, чтобы позиционировать нашу статью по центру добавим: mx-auto элементу

.card <div className="card mx-auto" style={style}>



Теперь нам остается убрать маркер списка.

Для этого мы напишем в файле ArticleList.js специальный стиль для тега li, а за одно научимся создавать собственные css-модули.

Нам придется создать отдельный css- файл для нашего ArticleList.js и в таких случаях, чтобы не создавать путаницу в общей папке компонентов, лучше создать для такого компонента отдельную папку!

Подключением файла стилей React - компоненту.

В папке components мы создадим отдельную папку -> ArticleList внутри которой мы будем держать реактовский код index.js, так и стили ArticleList.js

В файл index.js мы вставим весь код из нашего ArticleList.js, только поправим пути:

index.js

  import React from 'react'
  import Article from '../Article'
  import './style.css'
  export default function ArticleList({articles}) {
        const articleElements = articles.map(article =>
            <li key = {article.id} className="article-list__li">
              <Article article = {article}/>
            </li>
          )
        return(
            <ul>
              {articleElements}
            </ul>
          );
  }



и здесь же создадим файл style.css -здесь будут стили данного компонента.

Файл ArticleList.js удаляем.

При этом webpack поймет, что в App.js ->ArticleList - это папка, и коль в ней есть файл index.js, то он возьмет именно этот файл. Поэтому файл index.js не нужно отдельно указывать в этом пути (т.е делать так - > import ArticleList from './ArticleList/index.js')
App.js

  import React from 'react'
  import ArticleList from './ArticleList'
  import articles from '../fixtures.js'
  import 'bootstrap/dist/css/bootstrap.css'

  function App() {
    return (
      <div className="container">
        <div className="jumbotron">
          <h1 className="display-3">App Name</h1>
        </div>  
          <ArticleList articles={articles}/>
      </div>
    );
  }

  export default App



Теперь добавим стили компоненту в файле style.css

Лучше всего себя показала методология БЭМ (сайт в России с vpn - отдельное спасибо РосКомНадзору) Блок Элемент Модификатор от Яндекса. Вы можете с ней ознакомиться. Мы пока что запишем:

style.css

   .article-list__li {
     list-style: none;
    }



Теперь, для того, чтобы воспользоваться этими стилями. нам необходимо сделать импорт. Мы сделаем это на уровне нашего компонента в файле index.js import './style.css'

Теперь каждый раз, когда кто-то захочет подключать наш компонент, он будет его подключать вместе с соответствующими стилями.

Нам остается только добавить класс className="article-list__li" к тегу li

Сохраняем, и... Не пугайесь. Ваш компилятор может сломаться и получите такое предупреждение, вместо приложения.



Это происходит, потому что webpack ожидал файл ArticleList.js, а теперь он живет в папке.

Чтобы это исправить, достаточно перезапустить сервер -> Ctrl + C


    npm start



Для того. чтобы он собрал уже все с index.js Таким образом, мы с вами подключили Bootstrap к нашему React-приложению, научились добавлять стили инлайн двумя способами и научились подключать стили непосредственно к React - компонентам. сделав их по настоящему независимыми "строительными блоками" React - приложения.

Все статьи по React.js



Файлы, которые мы изменяли в этот раз:



components/App.js

  import React from 'react'
  import ArticleList from './ArticleList'
  import articles from '../fixtures.js'
  import 'bootstrap/dist/css/bootstrap.css'

  function App() {
    return (
      <div className="container">
        <div className="jumbotron">
          <h1 className="display-3">App Name</h1>
        </div>  
          <ArticleList articles={articles}/>
      </div>
    );
  }

  export default App





components/Article.js

  import React, {Component} from 'react'

  class Article extends Component {
        state = {
          isOpen: true
      }

    render() {
        const {article} = this.props
        const style = {width:'50%'}
        const body = this.state.isOpen && <section className="card-text">{ article.text }</section> 
      return(
        <div className="card mx-auto" style={style}>
          <div className="card-header">
            <h2>
                { article.title }
                <button onClick={this.handleClick} className="btn btn-primary btn-lg float-right">
                    {this.state.isOpen ? 'close' : 'open'}
                </button>
            </h2>
          </div>
          <div className="card-body"> 
                <h6 className="card-subtitle text-muted">
                   "creation date : "{ (new Date(article.date)).toDateString()}
                </h6>
                { body }
          </div>
        </div>
      );
    }
    handleClick = () =>{
      console.log('---', 'clicked')
      this.setState({
        isOpen: !this.state.isOpen
      })
    }
  }

  export default Article





components/ArticleList/index.js

  import React from 'react'
  import Article from '../Article'
  import './style.css'
  export default function ArticleList({articles}) {
        const articleElements = articles.map(article =>
            <li key = {article.id} className="article-list__li">
              <Article article = {article}/>
            </li>
          )
        return(
            <ul>
              {articleElements}
            </ul>
          );
  }





components/ArticleList/style.css

  .article-list__li {
    list-style: none;
  }



                                                                                                                                                             

Комментариев нет:

Отправить комментарий



Хотите освоить самые современные методы написания React приложений? Надоели простые проекты? Нужны курсы, книги, руководства, индивидуальные занятия по React и не только? Хотите стать разработчиком полного цикла, освоить стек MERN, или вы только начинаете свой путь в программировании, и не знаете с чего начать, то пишите через форму связи, подписывайтесь на мой канал в Телеге, вступайте в группу на Facebook.Пишите мне - kolesnikovy70 почта gmail.com