Translate

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

среда, 9 мая 2018 г.

React.js (2) Разбиваем на компоненты.

Хранить весь код в одном файле index.js неудобно и поэтому мы разобьем наш файл на компоненты.

Первая часть о том, как развернуть быстро и легко React приложение на локальном сервере находится здесь - React.js Настройка окружения.



Каждый компонент может быть повторно использован и представляет собой некую отдельную, самостоятельную часть (можно представить как строительный блок) кода. Будет правильным поместить их в отдельные файлы. Поэтому в папке src мы создадим для всех компонентов отдельную папку - components. В ней создадим два файла - Article.js и App.js.

В них мы поместим код (функцию) наших компонентов из файла index.js.

Затем, мы подключим к каждому файлу React, так как именно его переменная React участвует в строительстве приложения и выносить ее в глобальную область видимости является плохой практикой. Именно поэтому мы создадим к ней доступ в каждом файле наших компонентов.

Для этого мы пропишем строку import React from 'react' в самом начале файлов Article.js и App.js.

Теперь нам нужно произвести подключение наших компонентов. Для этого под функциями в файлах компонентов мы сделаем export наших компонентов. Например так:

export default App - для App - компонента.

export default Article - для Article - компонента.

В компонент App нам нужно импортировать код компонента Article, так как он принимает участие в строительстве самого App - компонента. вспоминаем:

function App() {
 return (
    <div>
        <h1>App Name</h1>
        <Article/>
    </div>
  );
}



Именно поэтому мы в фале App.js пишем - import Article from './Article'

После этих изменений стоит запустить сервер (в КС (bash) - npm start. см. Здесь! и убедиться, что все продолжает работать!

На данном этапе наш код компонента Article показывает статические названия, которые мы прописали внутри тегов title, body и т.д. Но нам нужно сделать таким образом, чтобы туда автоматически подставлялись текст, заголовок и прочие необходимые атрибуты статьи.

Для этого мы можем использовать js - переменные ( внутри фигурных скобок - { js-variable } ).

Наши компоненты (App и Article) это обычные функции и им в аргументы мы можем передавать нужные данные. Все данные будут приходить в первом аргументе и его принято называть props.

Коль скоро мы хотим получить в компоненте Article статью, то мы можем создать переменную const {article} = props - используем деструктуризацию объекта и все эти переменные мы сможем использовать внутри JSX.({ article.title }, { article.text } и пр.)

Файл Article.js

import React from 'react'

function Article(props) {
  const {article} = props
  const body = <section>{ article.text }</section> 
 return(
      <div>
        <h2>{ article.title }</h2> 
        { body }
        <h3>
         "creation date : "{ (new Date(article.date)).toDateString()}
        </h3>
      </div>
    );
}

export default Article



Файл App.js

import React from 'react'
import Article from './Article'

import articles from '../fixtures.js'

function App() {
 return (
    <div>
        <h1>App Name</h1>
        <Article article={articles[0]}/>
    </div>
  );
}

export default App



Здесь стоит пояснить, что строкой import articles from '../fixtures.js' мы подключаем файл в котором будут храниться сами статьи.

Для того, чтобы передать наши статьи article={articles[0]}
Файл fixtures.js

export default [
    {
        "id": "56c782f18990ecf954f6e027",
        "date": "2016-06-09T15:03:23.000Z",
        "title": "React Is Awesome!!!",
        "text": "React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. \n We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.",
        "comments": [
            {
                "id": "qwerqwer",
                "user": "Gilliam Underwood",
                "text": "Velit anim deserunt elit velit est fugiat duis eiusmod eu do incididunt ut tempor voluptate. Officia dolor aliqua id anim mollit pariatur id commodo. Laborum minim non ut aliquip commodo est consectetur. Mollit eu aliqua tempor est nulla ullamco irure. Sit non amet et eiusmod cillum ex cillum anim incididunt ad laboris mollit. Sunt quis incididunt elit ea qui non ullamco aliquip consequat voluptate eiusmod est. Irure laboris amet culpa sit aliquip."
            },
            {
                "id": "lkjhsdlfkg",
                "user": "Dolly Franklin",
                "text": "Aliquip id nostrud adipisicing irure. Labore reprehenderit ea ex officia ullamco incididunt consequat elit amet quis commodo. Fugiat amet veniam cillum ut aliquip velit est esse minim fugiat eiusmod sint. Commodo ea in culpa deserunt."
            },
            {
                "id": "zxcvzcxvzxcv",
                "user": "Brennan Atkins",
                "text": "Nisi sit nisi cillum dolor fugiat sint do nostrud ex cillum cupidatat. Culpa do duis non et excepteur labore dolor culpa qui tempor veniam. Ex labore deserunt qui sit aute ad incididunt do cupidatat eiusmod reprehenderit ad. Qui laborum qui voluptate velit et consectetur ipsum enim dolore minim. Est sint velit tempor reprehenderit. Qui consectetur ad minim consequat."
            },
            {
                "id": "fghjfghjfghj",
                "user": "Jodi Humphrey",
                "text": "Non amet amet ut magna culpa dolore consequat occaecat. Commodo adipisicing laboris voluptate enim mollit mollit anim aliquip deserunt nostrud deserunt cillum est. Ad eu cupidatat dolor nostrud et minim id in dolor occaecat ad magna elit. Laboris elit laboris aliquip Lorem reprehenderit id amet reprehenderit laborum minim incididunt cupidatat eiusmod."
            },
            {
                "id": "ertyoertywte",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f17b4e0ba78c7ad717",
        "date": "2016-04-09T18:03:23.000Z",
        "title": "Quis occaecat",
        "text": "Quis occaecat duis aliqua reprehenderit excepteur nisi deserunt excepteur elit magna. Magna cillum anim veniam deserunt voluptate occaecat irure fugiat laboris proident. Tempor do magna deserunt cillum laborum cillum ut.\n\nEst sunt cupidatat in deserunt sit aliqua duis. Mollit consequat duis aliquip occaecat pariatur non do eiusmod dolore amet deserunt ullamco. Ea minim tempor exercitation do tempor nostrud dolor minim veniam laboris commodo ex duis. Do nostrud voluptate ullamco consequat anim tempor voluptate incididunt aliqua tempor.\n\nIn irure quis nostrud do. Labore laboris irure culpa reprehenderit pariatur laboris in commodo culpa enim cillum magna. Magna ipsum pariatur sunt in reprehenderit ipsum duis officia voluptate adipisicing ad officia. Duis est sint mollit amet laborum magna non quis nulla ipsum in veniam sit. Amet velit consequat esse esse ea. Ipsum non do ut cillum in adipisicing labore non commodo do laborum sunt.",
        "comments": [
            {
                "id": "qwerqwertyy",
                "user": "Gilliam Underwood",
                "text": "Velit anim deserunt elit velit est fugiat duis eiusmod eu do incididunt ut tempor voluptate. Officia dolor aliqua id anim mollit pariatur id commodo. Laborum minim non ut aliquip commodo est consectetur. Mollit eu aliqua tempor est nulla ullamco irure. Sit non amet et eiusmod cillum ex cillum anim incididunt ad laboris mollit. Sunt quis incididunt elit ea qui non ullamco aliquip consequat voluptate eiusmod est. Irure laboris amet culpa sit aliquip."
            },
            {
                "id": "sdfgsdfghu7u7urtv",
                "user": "Jodi Humphrey",
                "text": "Non amet amet ut magna culpa dolore consequat occaecat. Commodo adipisicing laboris voluptate enim mollit mollit anim aliquip deserunt nostrud deserunt cillum est. Ad eu cupidatat dolor nostrud et minim id in dolor occaecat ad magna elit. Laboris elit laboris aliquip Lorem reprehenderit id amet reprehenderit laborum minim incididunt cupidatat eiusmod."
            }
        ]
    },
    {
        "id": "56c782f1978fdf9a0100df52",
        "date": "2016-06-02T11:03:23.000Z",
        "title": "Hello my new world",
        "text": "Culpa dolor deserunt veniam irure amet officia excepteur labore nisi labore ad labore laborum aute. Ea irure sit exercitation ex. Aliquip dolore duis ullamco labore qui. Et anim irure laborum quis ipsum. Adipisicing culpa est ea velit veniam dolor nisi. Sit cupidatat velit commodo eu.\n\nUt nulla ut irure cillum irure sint sunt cupidatat tempor laboris incididunt elit occaecat fugiat. Reprehenderit enim cupidatat consectetur pariatur ad pariatur consequat veniam do fugiat Lorem laborum do velit. Nulla aute magna magna nisi officia et. Aute adipisicing eu eiusmod tempor exercitation sint non enim laboris dolor adipisicing.\n\nEa do sint pariatur voluptate ad culpa irure. Cillum pariatur deserunt fugiat elit. Exercitation labore amet deserunt magna. Velit veniam aute officia aliqua ipsum veniam pariatur. Aliquip ullamco fugiat officia non sunt ad consequat ipsum est esse commodo reprehenderit. Ad quis consectetur est exercitation fugiat eiusmod. Laborum reprehenderit esse qui irure.",
        "comments": [
            {
                "id": "kjfviudfv089w74",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "r23uyrghasdfb7",
                "user": "Joyce Weber",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f1e17f4f9311dfaa2c",
        "date": "2016-05-19T23:03:23.000Z",
        "title": "Voluptate est officia",
        "text": "Voluptate est officia pariatur tempor labore consequat consequat consectetur culpa enim. Amet laborum commodo in ullamco magna aliquip. Cupidatat veniam adipisicing labore irure nostrud sunt proident aute in. Sit Lorem consequat cillum enim id excepteur aliqua nostrud sint quis aute est est dolor. Sunt culpa est magna ad qui consequat exercitation. Enim sit ex do cupidatat laborum.\n\nOccaecat do tempor ex in dolor cupidatat do quis laboris anim. Et duis esse pariatur magna ex ipsum ut do ut id cillum. Nostrud fugiat sit minim ea. Nisi nulla sunt et et voluptate. Velit reprehenderit enim nulla mollit dolore excepteur Lorem do Lorem do cillum est qui. Ipsum mollit duis laboris incididunt non sit sunt proident. Aute voluptate id sunt aute proident officia.\n\nEnim ut nulla cillum officia cupidatat eiusmod amet laborum do labore id. Laborum in laboris aliquip anim consectetur magna reprehenderit consequat eiusmod esse Lorem consequat aliqua. Eiusmod voluptate mollit sint consectetur eu deserunt laboris ad et sunt nulla fugiat quis non. Dolor qui do cupidatat proident mollit amet sint pariatur non aliquip enim ex.",
        "comments": [
            {
                "id": "rflsbvyeuwr334rg5",
                "user": "Random Name",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "234faasffasgfq3r3eda",
                "user": "Felix Soyferman",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
        ]
    },
    {
        "id": "56c782f197fe2bad471b3740",
        "date": "2016-06-04T15:03:23.000Z",
        "title": "Ex sunt sunt aliqua",
        "text": "Ex sunt sunt aliqua reprehenderit aliqua occaecat. Minim anim commodo officia veniam proident aute cillum eu sunt aute nostrud. Laboris fugiat velit ut pariatur occaecat adipisicing pariatur occaecat. Duis sint enim et consectetur quis pariatur laborum excepteur. Ipsum aliquip qui laborum commodo consectetur do velit veniam occaecat. Ad nisi dolor cillum elit magna dolor voluptate ea. Enim in duis ea consequat sunt Lorem aute.\n\nEst elit sunt quis officia reprehenderit do elit commodo eiusmod esse voluptate. Sit ipsum commodo sint voluptate culpa labore elit magna ullamco nostrud. Laboris magna magna anim labore mollit irure voluptate. Aute non magna aliqua aliqua sunt. Velit mollit consectetur aliqua id tempor ut. Tempor cupidatat aliquip excepteur occaecat incididunt nulla Lorem sint.\n\nNon commodo anim deserunt in et aliquip incididunt ut consectetur sunt esse commodo deserunt et. Tempor fugiat laboris cillum laboris labore. Deserunt quis ad do labore amet culpa officia. Esse et officia nostrud tempor occaecat officia anim incididunt amet sunt excepteur Lorem. Aute occaecat magna velit nisi sit anim consequat velit qui pariatur. Esse incididunt id officia aliqua anim ut et.",
        "comments": [
            {
                "id": "23rfasdfasdvg",
                "user": "Hello World",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "fqasfd4r35tga",
                "user": "Sofia Michailenko",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            }
        ]
    },
    {
        "id": "56c782f1a2c2c3268ddb3206",
        "date": "2016-06-08T19:03:23.000Z",
        "title": "Commodo laborum sit nostru",
        "text": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut.",
        "comments": [
            {
                "id": "23qwfasdf3",
                "user": "Brad McKeon",
                "text": "Non qui Lorem qui commodo sint in esse non aliqua pariatur mollit veniam. Elit labore ad nisi anim adipisicing tempor velit commodo adipisicing ipsum ut. Nostrud cillum aliquip adipisicing id do occaecat est eiusmod adipisicing duis. Magna dolore et non nisi in non cillum officia elit non esse proident irure aute. Proident mollit amet enim dolore eiusmod dolor qui. Eiusmod reprehenderit cillum sit deserunt nostrud enim duis excepteur. Excepteur pariatur sunt in ipsum id minim est mollit."
            },
            {
                "id": "dadsafw4f45w",
                "user": "Dolly Franklin",
                "text": "Aliquip id nostrud adipisicing irure. Labore reprehenderit ea ex officia ullamco incididunt consequat elit amet quis commodo. Fugiat amet veniam cillum ut aliquip velit est esse minim fugiat eiusmod sint. Commodo ea in culpa deserunt."
            },
            {
                "id": "234erasfdastw4a",
                "user": "Brennan Atkins",
                "text": "Nisi sit nisi cillum dolor fugiat sint do nostrud ex cillum cupidatat. Culpa do duis non et excepteur labore dolor culpa qui tempor veniam. Ex labore deserunt qui sit aute ad incididunt do cupidatat eiusmod reprehenderit ad. Qui laborum qui voluptate velit et consectetur ipsum enim dolore minim. Est sint velit tempor reprehenderit. Qui consectetur ad minim consequat."
            }
        ]
    },
    {
        "id": "56c782fghgfc2c3268ddb3206",
        "date": "2016-06-08T19:03:23.000Z",
        "title": "Lorem Ipsum dolor",
        "text": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut."
    }

]


Теперь наш сайт будет выглядеть так.



В props мы можем передавать все что угодно. Это объект, который может передавать в компонент данные. Например

<Article article={articles[0] foo="bar"}/> - передаем строку и нам не нужно заворачивать ее в фигурные скобки.

<Article article={articles[0] flag={ true }}/> передали флажок. Можно передать просто flag без значений и он передастся как true Таким образом мы разбили наше приложение на компоненты и связали их между собой. Подключили вывод текста одной статьи. Продолжение знакомства с React.js смотрите в следующей части - React.js (3) Там мы будем добавлять интерактивность нашим компонентам. Поставим кнопку с изменяющимся текстом для открытия\скрытия статьи.
Все статьи по React.js

                                                                                                                                                             

React.js (3) Добавляем интерактивность.



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



Добавляем кнопку к нашему приложению. Для этого в файле Articles.js добавили - выделено красным:

import React from 'react'

function Article(props) {
  const {article} = props
  const body = <section>{ article.text }</section> 
 return(
      <div>
        <h2>
          { article.title }
          <button onClick={handleClick}>close</button>
        </h2> 
        { body }
        <h3>
         "creation date : "{ (new Date(article.date)).toDateString()}
        </h3>
      </div>
    );
}
function handleClick() {
  console.log('---', 'clicked')
}

export default Article


Мы добавили кнопку и "проверочную" функция, которая при клике выведет в консоль:



Теперь самое время подумать, как мы будем открывать и закрывать текст статьи этой кнопкой.

В мире реакта мы используем декларативное программирование. То есть мы не описываем что нужно убрать этот текст или напротив - добавить текст в HTML. Мы описываем состояние компонента. И наши объекты могут находиться в различных состояниях. В нашем случае это состояния с открытым и закрытым текстом.

Мы опишем эти состояния, а кнопка будет нам помогать переходить из одного состояния в другое. Именно нажатие на кнопку будет изменять состояние компонента.

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

Для того, чтобы добавить описание состоянию компонента нам придется использовать второй синтаксис с использование классов ES6:

Для этого нам понадобится базовый компонент реакта - изменяем первую строку "импорта":


import React, {Component} from 'react'

class Article extends Component {
  render() {
    Cюда весь код функции Article без объявления
  }
}


Единственное что - наши props. Для них следует добавить - this.props, потому как они уже не будут приходить как аргумент, а будут частью компонента - Component, расширением коего и является наша функция Article

Проверим. Ничего не должно измениться на нашем сайте.

Теперь нам нужно добавить состояние. Для этого внутри компонента мы создадим конструктор в котором зададим начальное состояние


import React, {Component} from 'react'

class Article extends Component {
  // constructor(props) {
  //   super(props)

  //   this.state = {
  //     isOpen: true
  //   }
  // }
state = {
  isOpen: true
}

  render() {
      const {article} = this.props
      console.log('---', this.props)
      const body = <section>{ article.text }</section> 
    return(
      <div>
        <h2>
          { article.title }
          <button onClick={handleClick}>close</button>
        </h2> 
        { body }
        <h3>
          "creation date : "{ (new Date(article.date)).toDateString()}
        </h3>
      </div>
    );
  }
}



function handleClick() {
  console.log('---', 'clicked')
}

export default Article

Красным цветом мы описали состояние компонента по старому. А ниже, зеленым, описали то же самое, но новым стилем. Поэтому все что красное - можно смело закомментировать. Это совершенно эквивалентные записи просто короткая запись с экспериментальным синтаксисом.

Теперь, нам нужно использовать это состояние. Мы будем его использовать там, где мы создали переменную body и скажем. что если наше состояние активное (isOpen: true), то мы будем показывать эту секцию, а нет - значит рендерить пустоту.

Наше состояние храниться в this.state. Это специальный атрибут, наподобие this.props. Ниже написанный код можно выразить так: Если наше состояние isOpen (true), то мы показываем секцию, а если нет, то не показываем.


const body = this.state.isOpen && <section>{ article.text }</section> 



для эксперимента мы изменим и изначальное состояние на false.
Теперь если проверить, то наша статья будет скрыта.



Стоит изменить значение isOpen: на true и статья будет открыта (показана на экране).

Теперь нам осталось сделать так, чтобы изменять состояние.

для смены состояний есть специальный метод ,code>this.set state. Но для того, чтобы работать с контекстом, нам нужно привязать этот контекст к обработчику. существует множество способов как это сделать.

<button onClick={handleClick.bind(this)}>close</button>


Но так делать не стоит.

Мы можем описать этот метод в конструкторе :


import React, {Component} from 'react'

class Article extends Component {
  constructor(props) {
    super(props)

       this.state = {
      isOpen: true
    }
    this.handleClick = handleClick.bind(this)
  }


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

export default Article



Красным цветом - это старый развернутый синтаксис. Его можно смело заменить новым - выделен зеленым цветом. Все красное- из кода можно смело удалить!

Во вновь добавленную функцию (зеленым) мы добавили проверочный вывод в консоль. и this.setState() в которую мы передали объект у которого мы задаем новое состояние isOpen = true или isOpen = false, но мы можем отталкиваться от предыдущего состояния и изменять его - isOpen: !this.state.isOpen

setState() - операция асинхронная, поэтому там у нас будет старое состояние (!this.state.isOpen).

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

Осталось только поменять текст на кнопке -вместо надписи кнопки - "close", мы добавим функцию, которая будет изменять текст в зависимости от состояния:

{this.state.isOpen ? 'close' : 'open'}

Файл 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>
        <h2>
          { article.title }
          <button onClick={this.handleClick}>
            {this.state.isOpen ? 'close' : 'open'}
          </button>
        </h2> 
        { body }
        <h3>
          "creation date : "{ (new Date(article.date)).toDateString()}
        </h3>
      </div>
    );
  }
  handleClick = () =>{
    console.log('---', 'clicked')
    this.setState({
      isOpen: !this.state.isOpen
    })
  }
}

export default Article



Первая часть React                                                                                                                                                              

понедельник, 7 мая 2018 г.

React.js Настройка окружения.

Самый простой способ настроить среду для запуска приложения на react.js это установить готовый пакет Create React App от разработчиков Facebook



Почему приложение Create React App?


Просто потому. что вместе с ним мы получим готовый, настроенный сервер, Babel интерпретатор, Webpack для сборки и другие плюшки, в виде свободы в написании кода без префиксов для кросбраузерности и настроенную среду для тестирования и сборки приложения. В вашей среде будет все, что вам нужно для создания современного приложения React:
  • React, JSX и ES6.
  • Языковые дополнительные функции за пределами ES6, такие как spread operator объектов.
  • Dev-сервер, который накладывает на обычные ошибки.
  • Импортируйте файлы CSS и изображений непосредственно из JavaScript.
  • Autoprefixed CSS, поэтому вам не нужны -webkit или другие префиксы.
  • Сценарий сборки для объединения JS, CSS и изображений для производства с sourcemaps.


Для начала нам потребуется установленный Node.js с менеджером пакетов npm или yarn.

Чтобы проверить, установлен ли на ваш компьютер Node.js, а npm - пакеты к нему устанавливаются по умолчанию, то введите в КС - командной строке, или bash - node -v.Должны получит версию ноды. Например: v8.5.0




  1. Идем на сайт gitHub - create-react-app
    или его русскоязычный аналог - create-react-app-rus

  2. Устанавливаем приложение глобально. В КС - командной строке (или Bash) вводим:

    npm install -g create-react-app

  3. Ждем окончания установки и переходим в директорию (команда cd), где будет создаваться папка нашего приложения. В КС набираем:

    create-react-app my-app

    В данном случае - my-app - название папки вашего приложения.

  4. Открываем папку нашего проекта my-app в редакторе и удаляем из папки public все файлы кроме index.html




  5. В файле index.html удаляем все и добавляем самый простой код страницы:

  6. 
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <title>React App</title>
      </head>
      <body>
        
        <div id="root"></div>
    
      </body>
    </html>
    
    


  7. В папке src оставляем только файл index.js с кодом, где будет например такой код (файл полностью):

  8. 
    import React from 'react'
    import {render} from 'react-dom'
    
    function Article() {
      const body = <section>Footer</section> 
     return(
          <div className="hello" style={{color:"red"}}>
            <h2>title</h2>
            <section>body</section> 
            { body }
            <h3 style={{color:"red"}}>
             "creation date : "{ (new Date()).toDateString()}
            </h3>
          </div>
        );
    }
    
    function App() {
     return (
        <div>
            <h1>App Name</h1>
            <Article/>
        </div>
      );
    }
    
    render(<App/> ,document.getElementById('root'))
    
    
    


  9. Сохраняем и переходим непосредственно в наше приложение - >
    cd my-app

    A для запуска сервера на локальном хосте 3000 в КС набираем:
    npm start

    Появится сообщение, что сайт запущен на локальном хосте по адресу -http://localhost:3000




  10. Перейдите по этому адресу и вы должны увидеть вот такую страницу




  11. Остановить сервер - Ctrl + C


Создание нового и открытие старого приложения.


Теперь, когда у вас на машине установлен пакет create-react-app глобально, вы можете с легкостью его развернуть в любой папке для создания нового react-приложения. Это очень удобно. Я делаю так:

  1. выбираю директорию в проводнике и нажимаю правую кнопку мыши.




  2. В выпадающем меню выбираю - Git Bush Here

  3. Далее все, как в примере выше, с пункта 3, или просто делаю
    npm start
    для запуска уже созданного приложения на локальном хосте.


Надеясь, что вам было понятно и я не слишком утомил вас подробными объяснениями. Дело в том, что информации по React.js действительно много, но порой она больше касается теории, или опускает какие-то моменты, которые авторам кажутся очень простыми и само-собой разумеющиеся, но это осложняет жизнь начинающим пользователям. Да, и приятно, когда нужные, простые заметки всегда под рукой.

Подписывайтесь на мой блог и не забывайте поделиться, чтобы не потерять, если вам понравилось.

Следующая часть - React (2) - разбить на компоненты                                                                                                                                                              

четверг, 3 мая 2018 г.

ES6 для начинающих (3).


Часть 1 статьи можно прочитать здесь.

Часть 2 статьи.



Темы, которые я расскажу в этой статье:
  1. Array map
  2. Array filter
  3. Array reduce
  4. Template literals
  5. Imports and exports
  6. Destructuring objects and arrays
  7. Extend and super


Array Map

Оператор Map используется для выполнения конкретной операции над всеми элементами массива и возвращает массив с модифицированными элементами.

Это очень легко реализовать. Давайте посмотрим пример.

let arr = [1,2,3,4,5];
let modifiedArr = arr.map(function(element, index, arr) {
  return element * 10;
});
console.log(modifiedArr);
Output:
[10, 20, 30, 40, 50]



Как видите, map принимает функцию с тремя параметрами.
  1. Первый параметр - это сам элемент.
  2. Второй параметр - это индекс элемента.
  3. Третий параметр - это весь массив.


А также обратите внимание, что в конце мы должны вернуть некоторое значение. Которое будет измененным значением этого элемента. Если вы ничего не вернули, то конкретный элемент будет неопределенным.

Еще одна вещь, которую я хотел бы добавить, - второй и третий параметр, является необязательным. Обязателен только первый параметр.

let modifiedArr = arr.map(function(element) {
  return element * 10;
});



Как вы видите, map принимает функцию с одним параметром.

Хорошо. Давайте попробуем написать map со стрелочными функциями.

let modifiedArr = arr.map((element, index) => {
  console.log("index "+index);
  return element * 10;
});
console.log(modifiedArr);
Output:
index 0
index 1
index 2
index 3
index 4
[10, 20, 30, 40, 50]



Думаю, мне не нужно много объяснять. Это просто.

Последний пример.

let modifiedArr = arr.map(element => element * 10);
console.log(modifiedArr);



Если вы знаете, стрелочные функции хорошо, это легко понять. Но если нет, то я попытаюсь объяснить.

Здесь есть две вещи.
  1. Если у вас есть функция с единственным параметром, вам не нужны круглые скобки - (). В нашем случае элементом является параметром.
  2. И если у вас есть единственная строка как тело функции, вам не нужны фигурные скобки - {}, а также JS будет неявно возвращать значение после выполнения функции. Вам не нужно использовать ключевое слово return.


Array Filter

Фильтр массива используется для фильтрации всего массива на основе некоторого состояния. Фильтр массива принимает каждый элемент массива и проверяет его с заданным условием. Если элемент соответствует условию, он сохраняет элемент в массиве иначе, он удаляет элемент.

Давайте посмотрим пример.

let arr = [1, 2, 3, 4, 5, 6]
let modifiedArr = arr.filter(function(element, index, array) {
  return element % 2 == 0
});
console.log(modifiedArr);
Output:
[2, 4, 6]



Как видно из приведенного выше примера, filter, подобно map, принимает три параметра.

И мы должны вернуть логическое значение для каждого элемента массива. Если вы не вернете какое-либо логическое значение в конце, тогда фильтр примет его как false и удалит элемент.

Хорошо .. Давайте попробуем это в стрелочной функции.

let modifiedAarr = arr.filter((element, index) => element%2 == 0)



Надеюсь, вы поняли. И не забывайте об этом, только первый параметр является обязательным. Другие два параметра являются необязательными.

Array Reduce

Array Reduce используется для агрегирования всех элементов массива и возврата одного значения. Давайте посмотрим пример

let arr = [1,2,3,4,5,6]
let total= arr.reduce(function(sum, element, index, array) {
  return sum + element;
},0);
console.log("total is "+total);
Output:
total is 21



В отличие от filter и map, сокращение принимает функцию с четырьмя параметрами, а также дополнительный элемент. В нашем случае это 0.

Давайте посмотрим, как это работает.

Первый параметр - это элемент агрегатора. Он имеет сумму элементов в любой заданной точке. И это начальное значение определяется как дополнительный элемент. В нашем случае это 0.

Затем второй, третий и четвертый параметры такие же, как у filter и map.

Как и в функциях filter и map, вы должны вернуть конечный результат.

Давайте посмотрим другой пример.

let arr = [1,2,3,4,5,6];
let totalSum = arr.reduce(function(sum, element, index, array) {
  console.log(sum+"+"+element+"="+sum+element);
  return sum + element;
}, 10);
console.log("Total sum is "+ totalSum);
Output:
10 + 1 = 11
11 + 2 = 13
13 + 3 = 16
16 + 4 = 20
20 + 5 = 25
25 + 6 = 31
Total sum is 31



Надеюсь, это понятный пример. Обратите внимание, что я сначала установил начальное значение суммы sum, элемента агрегатора на 10.

Давайте напишем тот же код со стрелочными функциями.

let totalSum = arr.reduce((sum, element) => element+sum, 0)



Надеюсь, вы поняли. Это легко.

В отличие от filter и map, первые два параметра являются обязательными. Другие два являются необязательными.

Template Literals

Если вы знаете другие языки программирования, такие как ruby, python, то Template Literals для вас не новы.

Это новый синтаксис, который упрощает добавление выражений.

Template Literals используются для выполнения любых выражений JS.

Давайте посмотрим пример

let name = "Jon Snow";
let msg = `My name is ${name}`;
console.log(msg);
Output:
My name is Jon Snow



всё очень просто.

Вы также можете использовать многострочные строки- multi-line strings.

let msg = `My name
is ${name}`;
console.log(msg);
Output:
My name
is Jon Snow



Давайте посмотрим другой пример

let name = "Srebalaji";
let languages = () => {return "Ruby, Js, Java, Python"}
let msg = `My name is ${name}
My age is ${20+3}
And I code in ${languages()}`
Output:
My name is Srebalaji
My age is 23
And I code in Ruby, Js, Java, Python



Надеюсь, вы поняли. Идем дальше. Вы можете добавить любое выражение легко, а также многострочные строки (multi-line strings).

Imports and Exports

Импорт и экспорт модулей в ES6 - одна из полезных функций, которые вы увидите в современных библиотеках интерфейсов.

Я очень рекомендую поиграть с этой функцией в этом Plunk. Окружающая среда уже настроена в этом Plunk.

Хорошо .. Так импорт и экспорт работают в ES6.

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

Импорт используется для импорта переменных, функций, классов из других модулей.

Если вы не устали. то давайте посмотрим пример.

app.js
export let name = "Jon"
export let age = 23
index.js
import {name, age} from './app'
console.log(name);
console.log(age);
index.html

Output:
Jon
23



В приведенном выше примере мы определили две переменные name и age переменных и экспортировали их.

В другом файле мы импортировали переменные и получили доступ к их значениям.

Это очень просто.

Пойдем глубже.

app.js
export default const name = "Jon"
index.js
import name from './app.js'
console.log(name);
Output:
Jon



В приведенном выше коде вы видите, что мы использовали новое ключевое слово default - по умолчанию. Значения по умолчанию в основном используются, если вам нужно экспортировать одно значение, функцию или объект из модуля. И в модуле может быть только одно значение по умолчанию - default value.

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

Пример:

import n from './app.js'
console.log(n);
Output:
Jon



Как вы можете видеть, мы указали значение по умолчанию - n здесь.

Пойдем глубже.

app.js
let a = 10;
let b = 2;
let sum = () => a+b;
export {a,b}
export default sum
index.js
import * as variables from './app'
import addition from './app' // default value
console.log(variables.a);
console.log(variables.b);
console.log(addition());
Output:
10
2
12



В приведенном выше примере вы можете видеть, что мы экспортировали две переменные и функцию. И мы импортировали все переменные, используя *.

При импорте есть две вещи.
  1. Если вы используете * для импорта значений, вы должны использовать псевдонимы - alias, которые будут ссылаться на импортированные значения. В нашем примере мы использовали переменные - variables как псевдоним.
  2. Использование * для импорта значений не импортирует значение по умолчанию. Вы должны импортировать их отдельно.


import addition, * as variables from './app'



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

Надеюсь, вы поняли. :)

Destructuring objects and arrays

Деструктуризация является одной из полезных функций в ES6. И это очень просто использовать.

Приведем пример.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName, lastName, age} = person
console.log(firstName);
console.log(lastName);
console.log(age);
Output:
Jon
Snow
23



В приведенном выше коде вы можете видеть, что у нас есть объект person с несколькими ключами.

И мы создали три переменные firstName, lastName, age (то же самое, что и ключи объектов.) из самого объекта.

Чтобы выразить это простыми словами, мы создали три переменные извлечением ключей из объекта.

Давайте посмотрим другой пример

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName} = person
console.log(firstName);
Output:
Jon



В приведенном выше примере вы можете видеть, что мы извлекли из объекта только требуемые значения.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
const {firstName: name, age} = person
console.log(name);
console.log(age);
Output:
Jon
23



В приведенном выше примере вы можете видеть, что мы определили новое имя переменной и присвоили значение firstName.

Надеюсь, вы поняли. Это просто.

Давайте посмотрим, как деструктурировать массив - destructure array.

let arr [1, 2, 3, 4]
const [a, b, c, d] = arr;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
Output:
1
2
3
4



Надеюсь, вы уловили это из кода выше. Это просто.

Мы присваиваем каждому элементу массива переменную.

Давайте посмотрим другой пример.

let arr = [1,2,3,4,5,6]
let [a,b,,d,e] = arr
console.log(a);
console.log(b);
console.log(d);
console.log(e);
Output:
1
2
4
5



В приведенном выше коде вы можете видеть, что мы пропустили третий элемент массива. Помимо этого все так же, как в предыдущем примере.

Давайте посмотрим другой пример.

let person = {firstName: "Jon", lastName: "Snow", age: 23}
let displayName = ({firstName, lastName:last}) => {
  console.log(`${firstName} - ${last}`);
}
displayName(person);
Output:
Jon - Snow



Надеюсь, вы поняли. идем дальше.

Extend and Super

Если у вас есть опыт кодирования в OОП (объектно-ориентированном программировании), то >Extend - расширение и Super - супер не новы для вас.

Extend используется для создания подкласса из основного класса. Подкласс наследует все свойства основного класса и также может изменять свойства основного класса.

class Person{
 constructor(firstName, lastName, age) {
   this.firstName = firstName;
   this.lastName = lastName;
   this.age = age;
 }
 displayName() {
  return `${this.firstName} - ${this.lastName}`;
 }
}
class Employee extends Person {
 constructor(firstName, lastName, age, salary) {
  super(firstName, lastName, age);
  this.salary = salary;
 }
 displaySalary() {
  return `${this.salary}`;
 }
 displayName() {
  return super.displayName();
 }
 displayAge() {
  return this.age;
 }
}
let manager = new Employee("Jon", "Snow", 23, 100);
console.log(manager.displaySalary());
console.log(manager.displayName());
console.log(manager.displayAge());
Output:
100
Jon Snow
23



В приведенном выше коде вы можете видеть, что мы определили класс Person с конструктором и простой метод.

И тогда мы определили еще один класс Employee, который является подклассом, унаследованным от Person. Для этого мы использовали расширения - Extend. Надеюсь, что это ясно.

И затем мы использовали ключевое слово super, чтобы вызвать конструктор родительского класса. И мы также вызвали метод, объявленный в родительском классе, используя super.
Примечание: вы можете использовать this в подклассе только после вызова super. Если вы используете this перед вызовом super в подклассе, вы получите RefrenceError.

Итак, мы достигли трех вещей в приведенном выше коде
  1. Мы использовали расширения Extend для создания подкласса из родительского класса.
  2. Мы использовали super для вызова конструктора родительского класса.
  3. Мы использовали super для вызова метода, определенного в родительском классе.
Надеюсь, у вас это получилось :)

Здесь можно немного поиграть и потренировать свои знания


Часть 1 статьи здесь.

Часть 2 статьи здесь.






Автор: Srebalaji Thirumalai.
Перевод: Kolesnikov Yaroslav



                                                                                                                                                             

среда, 2 мая 2018 г.

ES6 для начинающих (2)


Первую часть этой статьи вы можете найти здесь.Там есть некоторые интересные функции. :)



Темы, которые я расскажу в этом посте
  1. Promises - Промисы (обещания)
  2. Async / Await


Promises

Promises - Обещания являются одной из полезных функций в ES6. Они используются для выполнения асинхронных операций, таких как запрос API, обработка файлов, загрузка изображений и т. д.

Итак, что такое Async? (держитесь, если вы уже знаете)

Асинхронные операции - это операции, требующие некоторого времени для завершения.

Например, скажем, вы определяете функцию, которая делает запрос API на сервер. Эта функция не возвращает результат немедленно. Для получения ответа от сервера требуется несколько секунд.

Поэтому, если вы вызываете эту функцию и присваиваете ее значение для некоторой переменной, она будет undefined не определено. Поскольку Javascript не знает, что функция обрабатывает некоторые операции async.

Итак, как мы справляемся с этим?

До этого поговорим немного о истории.

Перед обещаниями - promise программисты использовали обратные вызовы - callbacks. Обратные вызовы являются нормальными функциями в Javascript, который выполняется, когда операция async завершена.

Например, вы определяете функцию, которая делает запрос API на сервер. Затем вы указываете функцию обратного вызова, которая будет выполняться, когда мы получим ответ от сервера.

Таким образом, в приведенном выше случае Javascript не останавливает выполнение, пока мы не получим ответ от API. И мы определили функцию callback, которая будет выполнена после получения ответа. Думаю, это понятно.

Итак, что такое обещания - promises





Обещания promises- это объекты, которые помогают выполнять асинхронные операции.

Технически это объекты, которые представляют собой завершение операции async. (Если вы что-то не получите, то остаетесь на некоторое время.)

Прежде чем объяснять, как определить обещание promises, я объясню жизненный цикл обещания.

У нас есть три состояния в promises.
  1. Pending Ожидание: в этом состоянии обещание (promises) просто выполняет операцию async. Например, он делает некоторый запрос API на сервер или загружает некоторые изображения из cdn. Из этого состояния (promises) обещания можно перейти либо к Fulfilled - исполнению, либо к Rejected - отказу.
  2. Fulfilled : Если (promises) обещание достигло этого состояния, значит, операция async завершена, и у нас есть выходные данные - output. Например, у нас есть ответ от API.
  3. Rejected : Если (promises) обещание достигло этого состояния, это означает, что асинхронная операция не увенчалась успехом, и у нас есть ошибка, из-за которой операция завершилась неудачей.


Хорошо ... Давайте посмотрим на некий код.

const apiCall = new Promise(function(resolve, reject) {
 // async operation is defined here...
});



Promise определяется созданием конструктора с использованием ключевого слова - new. Тогда конструктор будет иметь функцию (мы называем ее executor function - функцией-исполнителем).

Асинхронная операция определяется внутри функции-исполнителя.

Обратите внимание, что функция-исполнитель имеет два параметра, которые resolve - разрешают или reject - отклоняют.

Первое решение параметра - фактически функция. Он вызывается внутри функции-исполнителя и представляет, что операция async успешна, и мы получаем результат. Функция Resolve помогает обещать перейти от pending -ожидаемого к fulfilled - исполненному состоянию. Надеюсь, вы поняли. :)

Подобно решению, reject также является функцией. Он также вызывается внутри функции-исполнителя, и он показывает, что операция async не выполняется, и мы получили ошибку. Отклонение помогает обещанию перейти от ожидания - pending к отклонению - reject. :)

const apiCall = new Promise(function(resolve, reject) {
 if ( API request to get some data ) {
  resolve("The request is successful and the response is "+ response);
 }
 else {
  reject("The request is not successful. The error is "+error);
 }
});



В приведенном выше коде вы можете видеть, что мы выполнили некоторую асинхронную операцию внутри функции-исполнителя. Затем вызывается функция resolve разрешения, если мы получаем ответ от сервера. И если есть некоторая ошибка, то функция reject error вызывается с сообщением об ошибке.

Мы сделали определение promises - обещания. Давайте посмотрим, как выполнить promises - обещание и обработать результат.

// calling the promise.
apiCall



Это оно. мы сделали. :) :)

Просто шучу. Это еще не конец.

В приведенном выше коде функция вызывается и выполняется обещание (т. Е. Выполняется executor function исполнительская функция). Затем вызывается функция resolve - разрешения или reject -отклонения на основе вывода - output.

Но вы можете видеть, что мы не обрабатывали результат, полученный из promise- обещания.

Например, если мы получим ответ от API, мы должны обработать ответ. Или, если мы получим ошибку, нам нужно правильно ее обработать.

Итак, как мы справляемся с этим?

Мы используем обработчики - handlers для получения результата от обещания.

Обработчики (handlers)- это просто функции, которые выполняются, когда происходит какое-то событие, например, нажатие кнопки, перемещение курсора и т. д.

Таким образом, мы можем использовать обработчики для обработки при вызове функции resolve - разрешения или reject - отклонения функции.

Просто. :)

Давайте посмотрим, такой код:

// calling the promise with some handlers.
apiCall.then(function(x) {console.log(x); })



В приведенном выше коде мы приложили обработчик (handler) к (then) обещанию (promise). Затем - then обработчик получает параметр функции. Тогда сам параметр функции имеет параметр x.

Так что происходит.

Обработчик then выполняет function parameter, когда функция resolve вызывается внутри обещания (promise).

Я попытаюсь объяснить это снова.

Обработчик then ищет случай, когда вызывается функция разрешения. Поэтому, когда функция разрешенияresolve вызывается, then обработчик выполняет свой параметр функции.

apiCall.then(function(x) {console.log(x); })
// Output
The request is successful and the response is {name: "Jon Snow"}



Аналогично, есть еще один catch захват обработчика.

Обработчик catch ищет функцию отклонения - reject .

Функция catch выполняет свой функциональный параметр при вызове функции reject.

apiCall.then(function(x) {console.log(x); }).catch(function(x) {console.log(x); })
// Assuming the request is not successful ( reject function is called in the promise. )
Output:
The request is not successful



Думаю, вы поняли.

Вышеприведенный код недостаточно читабельен. Так давайте попробуем:

apiCall
.then(function(x) {
 console.log(x); 
})
.catch(function(x) {
 console.log(x);
}) 



Теперь это можно прочитать. Большинство программистов пишут это так.

Хорошо. Поэтому я думаю, что вы прошли долгий путь.

Давайте резюмировать..
  1. Promise определяется с помощью нового ключевого слова с параметром функции. Тогда сама функция имеет два параметра функции, которые разрешают - resolve и отклоняют - reject.
  2. Функция resolve будет вызвана, когда операция выполнена успешно.
  3. Функция reject - когда операция даст сбой.
  4. Обработчик then ищет функцию resolve разрешения.
  5. Обработчик catch ищет функцию reject отклонения.
  6. Удостоверьтесь в удобочитаемости кода :) :)
Вот рабочий пример - jsfiddle.net. Пожалуйста, попрактикуйтесь, если вы новичок в этом.


Надеюсь,что вы поймете пример. Тогда вперед.

Async / Await

Если вы понимаете Promise, то Async / Await довольно легко. И если вы не поняли Promise, Async / Await может помочь вам понять это. Может быть, вы также сможете получить ясный выход из Promise - обещаний. :)

Async

Ключевое слово Async позволяет любой функции возвращать только обещания.

Например, рассмотрите приведенный ниже код

async function hello() {
 return "Hello Promise..!"
}



Function hello вернет Promise - обещание.

Вышеприведенный код эквивалентен приведенному ниже коду.

function hello() {
 return new Promise(function(resolve, reject) {
 // executor function body.
 });
}



Так проще?

Другой пример:

async function hello(a, b) {
 if (a < b) {
  return "Greater";
 }
 else {
  return new Error("Not Greater");
 }
}
hello(14, 10)
.then(function(x) {
 console.log("Good..! " + x); 
})
.catch(function(x) {
 console.log("Oops..! " + x); 
})
Output:
Oops..! Not Greater. 
// if you call hello(4, 10) you get "Good..! Greater"



В приведенном выше коде мы определили функцию async и вернули некоторое значение или вернули некоторую ошибку.

Если вы возвращаете некоторое значение в async-функции, это эквивалентно вызову функции resolve разрешения.

Если вы возвращаете некоторую ошибку, вызывая error constructor using ‘new’ (конструктор ошибок с помощью «new»), то это эквивалентно функции reject - отклонения.

Не забывайте, что функция async вернет обещание. Поэтому, конечно, вы можете вызвать функцию resolve - разрешения и отклонения - reject внутри функции async.

Посмотрим, как это работает.

async function Max(a, b) {
 if (a > b) {
  return Promise.resolve("Success");
 }
 else {
  return Promise.reject("Error");
 }
}
Max(4, 10)
.then(function(x) {
 console.log("Good " + x); 
})
.catch(function(x) {
 console.log("Oops " + x); 
});
Output:
Oops Error
// If we pass Max(14, 10) then we should get "Good Success" :)



Await

Как следует из названия, это заставляет Javascript ждать завершения операции. Предположим, вы делаете запрос API с ключевым словом await. Это заставляет Javascript ждать, пока вы не получите ответ от конечной точки. И затем он возобновляет выполнение.

Хорошо .. Пойдем глубже

Ожидание await может использоваться только внутри асинхронной функции. Он не работает вне асинхронной функции
Давайте посмотрим пример:

async function hello() {
 let response = await fetch('https://api.github.com/');
 // above line fetches the response from the given API endpoint.
 return response;
}
hello()
.then(function(x) {
 console.log(x); 
});
...
...
Output:
Response from the API.



В приведенном выше коде вы можете видеть, что мы использовали await ожидание при получении ответа от API.

Операция выборки (fetch) может занять несколько секунд, чтобы получить ответ так, что выполнение будет остановлено и возобновлено позже.

Обратите внимание, что ожидание операции останавливает выполнение внутри функции hello. Остающийся код вне функции hello не будет затронут. Выполнение продолжается вне функции. И когда мы получаем ответ, выполняется параметр функции .then внутри обработчика .

Надеюсь, вы поняли.

Давайте посмотрим пример

jsfiddle.net



В приведенном выше примере вы можете видеть, что мы использовали await функцию для getResponse. И getResponse вернет результат или ошибку через 5 секунд. Таким образом, до этого времени выполнение приостанавливается, а затем возвращается ответ.

Давайте посмотрим пример в реальном времени.

jsfiddle.net



В приведенном выше примере вы можете видеть, что мы использовали несколько ожиданий - awaits. Поэтому для каждого ожидания выполнение останавливается до получения ответа, а затем возобновляется.

Попробуйте использовать тот же пример с некорректным URL-адресом. Вы можете видеть, что ошибка поднята.

Обработка ошибок очень проста в асинхронной async функции. Если ошибка возникает внутри функции async или когда ошибка возникает из других функций, которые вызываются внутри async, используя await, вызывается функция reject - отклонения. Просто.

Надеюсь тебе понравилось. Я рассмотрю гораздо более интересные темы, такие как карта массива, фильтр массивов, сокращение и т. д. В следующей части.




Автор: Srebalaji Thirumalai.
Перевод: Kolesnikov Yaroslav




                                                                                                                                                             

вторник, 1 мая 2018 г.

ES6 для начинающих. (1)

В этом посте я расскажу о некоторых новых функциях в ES6. Это будет полезно, если вы новичок в ES6 или изучаете front-end frameworks.




Темы, которые я расскажу в этом посте
  1. Let и Const.
  2. Стрелочные функции.
  3. Параметры по умолчанию.
  4. Цикл for.
  5. Spread атрибуты - Spread attributes.
  6. Maps.
  7. Sets.
  8. Статические методы.
  9. Геттеры и Сеттеры - Getters and Setters.


Let

Let аналогичен var, но let имеет область видимости. let доступен только на уровне блока, где он определен.


if (true) {
 let a = 40;
 console.log(a); //40
}
console.log(a); //



В приведенном выше примере переменная 'a' определяется внутри оператора If и поэтому недоступна вне функции.

Другой пример:

let a = 50;
let b = 100;
if (true) {
 let a = 60;
 var c = 10;
 console.log(a/c); // 6
 console.log(b/c); // 10
}
console.log(c); // 10
console.log(a); // 50



Const

Константа используется для назначения постоянной переменной переменной. И значение её не может быть изменено. Это фиксированная переменная.


const a = 50;
a = 60; // shows error. You cannot change the value of const.
const b = "Constant variable";
b = "Assigning new value"; // покажет ошибку.



Рассмотрим другой пример.
const LANGUAGES = ['Js', 'Ruby', 'Python', 'Go'];
LANGUAGES = "Javascript"; // покажет ошибку
LANGUAGES.push('Java'); // сработает.
console.log(LANGUAGES); // ['Js', 'Ruby', 'Python', 'Go', 'Java']


Это может казатся немного запутанным.

Рассмотрим это таким образом. Всякий раз, когда вы определяете константную (постоянную) переменную, Javascript ссылается на адрес значения переменной. В нашем примере переменная 'LANGUAGES' фактически ссылается на память, выделенную для массива. Поэтому вы не можете изменить эту переменную, чтобы позже ссылаться на другую ячейку памяти. Всюду по программе она ссылается только на массив.

Стрелочные функции - Arrow Function

Функции в ES6 немного изменились. Я имею в виду синтаксис.


// Old Syntax
function oldOne() {
 console.log("Hello World..!");
}
// New Syntax
var newOne = () => {
 console.log("Hello World..!");
}



Новый синтаксис может немного запутать. Но я попытаюсь объяснить синтаксис.

Есть две части синтаксиса.

Первая часть просто объявляет переменную и присваивает ей функцию (). Она просто говорит, что переменная на самом деле является функцией.

Затем вторая часть объявляет часть тела функции. Часть стрелки с фигурными скобками определяет часть тела.

Другой пример с параметрами.

let NewOneWithParameters = (a, b) => {
 console.log(a+b); // 30
}
NewOneWithParameters(10, 20);



Я не думаю, что мне нужно давать объяснение этому. Это просто.

Более подробно об этих функциях я рассказываю в посте ES6: Стрелочные функции (XI).

Параметры по умолчанию - Default Parameters

Если вы знакомы с другими языками программирования, такими как Ruby, Python, то параметры по умолчанию для вас не новы.

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

Пример:

let Func = (a, b = 10) => {
 return a + b; 
}
Func(20); // 20 + 10 = 30



В приведенном выше примере мы передаем только один параметр. Функция использует параметр по умолчанию и выполняет функцию.

Рассмотрим другой пример:

Func(20, 50); // 20 + 50 = 70



В приведенном выше примере функция принимает два параметра, а второй параметр заменяет параметр по умолчанию.

Рассмотрим другой пример:

let NotWorkingFunction = (a = 10, b) => {
 return a + b;
}
NotWorkingFunction(20); // NAN. Not gonna work.



Когда вы вызываете функцию с параметрами, они назначаются в порядке. Первое значение присваивается первому параметру, а второе значение присваивается второму параметру и т. д.

В приведенном выше примере значение 20 присваивается параметру «a», а «b» не имеет значения. Таким образом, мы не получаем никакой информации.

Но,

NotWorkingFunction(20, 30); // 50;



Работает отлично.

Цикл for - For of loop

Цикл for очень похож на цикл for in в легкой модификации. Цикл for проходит через список элементов (например, типа Array) и возвращает элементы (а не их индекс) один за другим.


let arr = [2,3,4,1];
for (let value of arr) {
 console.log(value);
}
Output:
2
3
4
1



Обратите внимание, что переменная 'value' выводит каждый элемент в массиве, а не индекс.

Другой пример

let string = "Javascript";
for (let char of string) {
 console.log(char);
}
Output:
J
a
v
a
s
c
r
i
p
t



Да. Он также работает для строки.

Spread атрибуты - Spread attributes

Атрибуты спреда помогают распространять выражение, как следует из названия. Простыми словами он преобразует список элементов в массив и наоборот.

Пример без атрибутов распространения - Spread attributes:

let SumElements = (arr) => {
 console.log(arr); // [10, 20, 40, 60, 90]
let sum = 0;
 for (let element of arr) {
 sum += element;
 }
 console.log(sum); // 220. 
}
SumElements([10, 20, 40, 60, 90]);



Вышеприведенный пример прост. Мы объявляем функцию принимающую массив как параметр и возвращать его сумму. Это просто.

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

let SumElements = (...arr) => {
 console.log(arr); // [10, 20, 40, 60, 90]
let sum = 0;
 for (let element of arr) {
 sum += element;
 }
 console.log(sum); // 220. 
}
SumElements(10, 20, 40, 60, 90); // Note we are not passing array here. Instead we are passing the elements as arguments.



В приведенном выше примере атрибут spread преобразует список элементов (например, параметры) в массив.

Другой пример:

Math.max(10, 20, 60, 100, 50, 200); // returns 200.



Math.max - простой метод, который возвращает максимальный элемент из данного списка. Он не принимает массив.


let arr = [10, 20, 60];
Math.max(arr); // Shows error. Doesn't accept an array.



Так что давайте использовать нашего спасителя.

let arr = [10, 20, 60];
Math.max(...arr); // 60



В приведенном выше примере атрибут spread преобразует массив в список элементов.

Maps

Map содержит пары ключ-значение. Он похож на массив, но мы можем определить наш собственный индекс. И индексы уникальны в map.

Пример:

var NewMap = new Map();
NewMap.set('name', 'John'); 
NewMap.set('id', 2345796);
NewMap.set('interest', ['js', 'ruby', 'python']);
NewMap.get('name'); // John
NewMap.get('id'); // 2345796
NewMap.get('interest'); // ['js', 'ruby', 'python']



Я думаю, что приведенный выше пример является самоочевидным.

Другие интересные особенности map - все его индексы уникальны. И мы можем использовать любое значение в качестве ключа или значения.

Пример:

var map = new Map();
map.set('name', 'John');
map.set('name', 'Andy');
map.set(1, 'number one');
map.set(NaN, 'No value');
map.get('name'); // Andy. Note John is replaced by Andy.
map.get(1); // number one
map.get(NaN); // No value



Другие полезные методы, используемые в Map:


var map = new Map();
map.set('name', 'John');
map.set('id', 10);
map.size; // 2. Returns the size of the map.
map.keys(); // outputs only the keys. 
map.values(); // outputs only the values.
for (let key of map.keys()) {
 console.log(key);
}
Output:
name
id



В приведенном выше примере map.keys () возвращает ключи map, но возвращает его в объекте Iterator. Это означает, что он не может отображаться так, как есть. Он должен отображаться только путем итерации.

Другой пример:

var map = new Map();
for (let element of map) {
 console.log(element);
}
Output:
['name', 'John']
['id', 10]



Вышеприведенный пример является самоочевидным. Цикл for..of выводит пару ключ-значение в массиве.

Мы можем немного его оптимизировать.

var map = new Map();
for (let [key, value] of map) {
 console.log(key+" - "+value);
}
Output:
name - John
id - 10



Наборы - Sets.

Наборы используются для хранения уникальных значений любого типа. Просто..!

Пример:

var sets = new Set();
sets.add('a');
sets.add('b');
sets.add('a'); // We are adding duplicate value.
for (let element of sets) {
 console.log(element);
}
Output:
a
b



Обратите внимание, что не отображаются повторяющиеся значения. Отображаются уникальные значения.

А также обратите внимание, что наборы являются итерируемыми объектами. Нам нужно перебирать элементы для отображения.

Другие полезные методы:

var sets = New Set([1,5,6,8,9]);
sets.size; // returns 5. Size of the set.
sets.has(1); // returns true. 
sets.has(10); // returns false.



В приведенном выше примере размер не требует пояснений. Существует еще один метод has, который возвращает логическое значение, основанное на том, присутствует ли данный элемент в наборе или нет.

Статические методы - Static methods

Большинство из вас уже слышали о статических методах. Статические методы вводятся в ES6. И это довольно легко определить и использовать.

Пример:

class Example {
 static Callme() {
 console.log("Static method");
 }
}
Example.Callme();
Output:
Static method



Обратите внимание, что я не использовал ключевое слово function внутри класса.

И я могу вызвать функцию без создания какого-либо экземпляра для класса.

Геттеры и сеттеры - Getters and Setters

Getters и seters и одна из полезных функций, введенных в ES6. Это пригодится, если вы используете классы в JS.

Пример без геттеров и сеттеров:

class People {
constructor(name) {
 this.name = name;
 }
 getName() {
 return this.name;
 }
 setName(name) {
 this.name = name;
 }
}
let person = new People("Jon Snow");
console.log(person.getName());
person.setName("Dany");
console.log(person.getName());
Output:
Jon Snow
Dany



Я думаю, что приведенный выше пример не требует пояснений. У нас есть две функции в классе Люди, которые помогают установить и получить имя человека.

Пример с геттерами и сеттерами

class People {
constructor(name) {
 this.name = name;
 }
 get Name() {
 return this.name;
 }
 set Name(name) {
 this.name = name;
 }
}
let person = new People("Jon Snow");
console.log(person.Name);
person.Name = "Dany";
console.log(person.Name);



В приведенном выше примере вы можете увидеть, что внутри класса People есть две функции «get» и «set». Свойство «get» используется для получения значения переменной, а свойство «set» используется для установки значения переменной.

И вы можете видеть, что функция getName вызывается без скобок. И функция setName вызывается без скобок, и это точно так же, как присвоение значения переменной.

Спасибо за ваше время. Надеюсь, вам понравилась статья. :) :) promises and async/await

Надеюсь тебе понравилось. Я рассмотрю гораздо более интересные темы, такие как promises and async/await и т. д. В следующей части.




Автор: Srebalaji Thirumalai.
Перевод: Kolesnikov Yaroslav




                                                                                                                                                             


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