a2a2543d-1502-4fac-9336-8f9627510105

Поговорим о нашем домашнем задании. Стоит отметить что при разработке decorators/mixins вся логика в большинстве случаев работает прекрасно. Она была реализована нами в классе, для выполнения домашнего задания оставалось вынести ее в decorator и соответствующий mixin. Так будет выглядеть наш decorator (src/decorators/oneOpen.js):

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:

openItemId: id == this.state.openItemId ? null : id

Наш mixin (src/mixins/oneOpen.js) будет выглядеть следующим образом:

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 измениться следующим образом:

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 будет выглядеть так:

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’а:

import ArticleList from './ArticleListOld

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

Read More:  17. Уроки Node.js. Таймеры, Отличия от Браузера, ref и unref

435258_8a75_3

We are looking forward to meeting you on our website blog.soshace.com

Share.

Comments are closed.

Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.