Все статьи по 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



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