Translate

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

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

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                                                                                                                                                              

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

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



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