Уроки React. Урок 4. Домашнее Задание.
Поговорим о нашем домашнем задании. Стоит отметить что при разработке decorators/mixins вся логика в большинстве случаев работает прекрасно. Она была реализована нами в классе, для выполнения домашнего задания оставалось вынести ее в decorator и соответствующий mixin. Так будет выглядеть наш decorator (src/decorators/oneOpen.js):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import React, { Component as ReactComponent} from 'react' export default (Component) => class OneOpen extends ReactComponent { state = { openItemId: null } openItem = openItemId => ev => { if (ev) ev.preventDefault() this.setState({ openItemId }) } toggleOpenItem = id => ev => { if (ev) ev.preventDefault() this.setState({ openItemId: id == this.state.openItemId ? null : id }) } isItemOpen = id => this.state.openItemId == id render() { return <Component {...this.props} isItemOpen = {this.isItemOpen} openItem = {this.openItem} toggleOpenItem = {this.toggleOpenItem}/> } } |
Decorators и mixins создаются для того чтобы вы могли переиспользовать ваш код, т.е. написав его однажды,применять его в разных местах. То что сегодня работает для статей завтра будет работать для комментариев, авторов и.т.п. Поэтому при присваивании имен вашим сущностям делайте более универсальные названия. К примеру: openItem, openElement. Для того чтобы сделать опциональную часть домашнего задания достаточно проверить когда нам приходит id, совпадает ли он с тем который у нас уже храниться в state. Если да, это означает что нам нужно закрыть статью, чтобы это сделать достаточно присвоить null, а иначе мы просто поменяем id:
1 | openItemId: id == this.state.openItemId ? null : id |
Наш mixin (src/mixins/oneOpen.js) будет выглядеть следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | export default { getInitialState() { //this.props return { openItemId: false } }, openItem(openItemId) { return ev => { if (ev) ev.preventDefault() this.setState({openItemId}) } }, toggleOpenItem(id) { return ev => { if (ev) ev.preventDefault() this.setState({ openItemId: id == this.state.openItemId ? null : id }) } }, isItemOpen(id) { return this.state.openItemId == id } } |
Также ArticleList.js измениться следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import React, { Component } from 'react' import Article from './Article' import oneOpen from './decorators/oneOpen' class ArticleList extends Component { render() { const { articles, isItemOpen, toggleOpenItem } = this.props const listItems = articles.map((article) => <li key={article.id}> <Article article = {article} isOpen = {isItemOpen(article.id)} openArticle = {toggleOpenItem(article.id)} /> </li>) return ( <div> <h1>Article list</h1> <ul> {listItems} </ul> </div> ) } } export default oneOpen(ArticleList) |
ArticleListOld.js будет выглядеть так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import React, { Component } from 'react' import Article from './Article' import oneOpen from './mixins/oneOpen' const ArticleList = React.createClass({ mixins: [oneOpen], render() { const { articles } = this.props const listItems = articles.map((article) => <li key={article.id}> <Article article = {article} isOpen = {this.isItemOpen(article.id)} openArticle = {this.toggleOpenItem(article.id)} /> </li>) return ( <div> <h1>Article list</h1> <ul> {listItems} </ul> </div> ) } }) export default ArticleList |
Пожалуйста добавьте следующую запись в app.js, и удалите import ArticleList’а:
1 | import ArticleList from './ArticleListOld |
Пожалуйста сравните наш код с тем что у Вас получился, и мы пойдем дальше. Все коммиты Вы сможете найти в репозитории.
We are looking forward to meeting you on our website soshace.com
Sign in \ Sign Up
Or use email\username to sign in
By Signing In \ Signing Up, you agree to our privacy policy