14Sep

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

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

435258_8a75_3

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

Уроки React. Урок 5.

Для того чтобы проверить нашу структуру следует пользоваться React dev tools. Скачать их можно здесь. Позволяет нам наблюдать всю структуру Вашего Virual DOM, Ваших компонентов и сторонние компоненты. Также здесь есть доступ к данным, можно посмотреть их Props,State и.т.п. Ставиться оно как расширение для вашего браузера и будет доступна при вызове инструментов разработчика. Для начала работы с React либо с новым проектом это очень полезно. Здесь видны названия ваших компонентов, например OneOpen, ArticleList, CommentList и др.
Допустим если не называть class OneOpen то в DevTools будет непонятно какой код отвечает за работу компонента к примеру, а вот называя его вы облегчаете себе дальнейший Debug.

Уроки React . Урок 9

Всем привет! Сегодня начнем наш урок с домашнего задания, сделав его вместе. Главной целью этих уроков является помочь читателю научиться думать категориями данных – это является основой функционального программирования как такового. когда вы любую систему, например UI, вы описываете набором данных. Пока в наших уроках мы делали все самыми простыми способами. У нас были статьи которые содержат в себе все необходимое, счетчик который содержит в себе число и т.д. Мы пока не делали ничего сложнее, не объединяли все эти элементы, мы не думали какие данные стоит хранить в store а какие в state компонентов. Поэтому давайте все это обсудим. Во-первых, какие данные и где следует держать?