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.com

Уроки React. Урок 2, Домашнее задание.

Давайте пробежимся по нашему домашнему заданию. Смысл использования React это создание компонентов из вашего функционала, т.е. дробление приложение на маленькие независимые части. В нашем случае комментарии нужно сделать комментарии отдельным компонентами. Также хорошей практикой считается иметь как можно больше stateless компонентов. К примеру в нашем случае это файл comment.js.

16. Уроки Node.js. Событийный цикл, библиотека libUV. Часть 1.

Всем привет. Если вы привыкли глубоко вникать в происходящее, то эта статья для вас. Здесь мы разберем те вопросы, которые рано или поздно обязательно возникнут при разработке, и ответа на которые требует глубокого понимания, как именно работает Node.js. Например, здесь (serverAsync.js смотрите файлы нашего предыдущего урока) для чтения файла использован асинхронный вызов:

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

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