10Nov

react-logo_13_2

Теперь давайте это вызовем в containers/Articles.js , добавив такую запись вызывая action creater:

import { loadAllArticles } from '../AC/articles'

class Articles extends Component {
    static propTypes = {

    };

    componentDidMount() {
        this.props.loadAllArticles()
    }

А ниже в connect мы его обернем :

export default connect(({ articles, filters }) => {
    return {
        articles: filterArticles(articles, filters)
    }
}, {
    loadAllArticles
})(Articles)

А далее вызовем в  componentDidMount().

Также в reducer/articles.js мы  уберем defaultArticles которые мы с Вами создавали:

const defaultArticles = new OrderedMap({})

Не забудем подключить в import объект OrderedMap:

import { Record, OrderedMap } from 'immutable'

Теперь нужно подключить наш middleware в нашем store.

Делаем import:

import api from '../middlewares/api'

И добавляем ее в ряд с другими middleware например после randomID:

const enhancer = compose(
    applyMiddleware(dumbMiddleware, randomId, api, logger),
    window.devToolsExtension ? window.devToolsExtension() : f => f
)

Теперь если перезапустить приложение в console можно увидеть что происходит LOAD_ALL_ARTICLES_SUCCESS

Давайте добавим setTimeout для симуляции некого далекого API, добавим это в middlewares/api.js:

   setTimeout(() => {
        $.get(callAPI)
            .done(response => next({type: type + SUCCESS, response, ...rest}))
            .fail(error => next({type: type + FAIL, error, ...rest}))
    }, 1000)
}

Теперь, если вы зайдет в console и перезагрузите наше приложение, у Вас произойдут действия  START и через секунду SUCCESS.

Теперь нам осталось научить наши reducers обращаться с новой логикой. Перейдем в reducer/articles.js.  Здесь нам уже недостаточно просто иметь articles в виде набора статей, поскольку наше приложение развивается, становиться более сложным, и появляется необходимость иметь информацию о статусе загрузки статей.

Подключим Map а также immutable массив  List из immutable.js:

import { Record, OrderedMap, Map, List } from 'immutable'

Опишем начальное состояние нашего reducer  , добавив следующую запись:

const defaultState = new Map({
    loading: false,
    loaded: false,
    errors: new List([]),
    entities: defaultArticles
})

Добавив сюда сами статьи у нас получилась структура, которую мы сможем переиспользовать от одного reducer к другому. Т.е. entities
у нас будут как статьи так и комментарии. Наш код ниже тоже  претерпит изменения:

export default (state = defaultState, action) => {
    const { type, payload, response, randomId } = action

    switch (type) {


        case ADD_COMMENT:
            return state.updateIn(['entities' ,payload.articleId, 'comments'], comments => comments.concat(randomId))

        case LOAD_ALL_ARTICLES + START:
            return state.set('loading', true)

        case LOAD_ALL_ARTICLES + SUCCESS:
            return state
                .set('loading', false)
                .set('entities', recordsFromArray(Article, response))
                //return state.update('entities', entities => entities.merge(recordsFromArray(Article, response)))

    }
   
    return state
}

Обратите Ваше внимание на закомментированную строку. Эта запись описывает подход как можно по-другому с помощью методов update и  merge из immutable.js загрузить наши статьи. В этом случаем мы  делаем обновление списка наших статей. Когда у нас приходит LOAD_ALL_ARTICLES + SUCCESS  мы берем старые entities  (если они у нас были) и делаем merge с новыми. По умолчанию, процесс добавления статей будет реализован нами c помощью set  – т.е. просто полным обновлением списка. Мы добавили .set('loading', ...), для того чтобы можно было добавить loader при загрузке наших статей.

Идем дальше, теперь нам нужно переписать логику того как мы получаем данные в filterArticles в containers/Articles.jsа также добавить loader в наш UI:

    render() {
        const { articles, loading } = this.props
        if (loading) return <h1>Loading...</h1>
        return <ArticleList articles = {articles} />
    }
}

export default connect(({ articles, filters }) => {
    return {
        loading: articles.get('loading'),
        articles: filterArticles(articles.get('entities'), filters)
    }
}, {
    loadAllArticles
})(Articles)

Мы добавили индикатор в export default), а  в render простенький loader. (когда мы закончим, до загрузки статей будет появлятся соответствующая надпись “Loading”).
В immutable.js вы должны явно писать ваше обращение  для того чтобы получить данные articles.get('entities'). Когда мы использовали immutable object Record мы могли избежать такого рода обращения, т.к. все происходило “под капотом” и getters, setters, создавались внутри, как в случае с const Article в reducer/articles.js.
Продолжим наши преобразования и изменим  reducer/articles.js  следующим образом:

import { DELETE_ARTICLE, ADD_COMMENT, LOAD_ALL_ARTICLES, START, SUCCESS } from '../constants'
import { Record, OrderedMap, Map, List } from 'immutable'
import { recordsFromArray } from './utils'

ошибки мы с Вами пока обрабатывать пока не будем. Запись про importnormalizedArticles нам здесь больше не понадобиться. Поменяем нашу константу defaultArticles :

const defaultArticles = recordsFromArray(Article, [])

И конечно же return в конце файла:

return state

Теперь все готово, можно проверять! Код нашего урока доступен по этой ссылке. До скорых встреч, дальше еще очень много интересного, увидимся!

react-boilerplate

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

1. Уроки Node.js .Модули. Часть 1.

Давайте создадим Ваш первый проект с Node.js. Нашей основной целью будет знакомство с модулями – способом который Node предлагает для организации проекта.

Установите Node на свой компьютер.

https://nodejs.org

19. Уроки Node.js. Безопасный Путь к Файлу в fs и path.

В этой статье мы рассмотрим, как при помощи Node.js создать веб-сервер, который будет возвращать файл пользователю из директории public. Может возникнуть вопрос: зачем здесь Node.js? почему бы не сделать это на другом сервере? Вопрос совершенно уместен. Да, для отдачи файлов, как правило, другие сервера будут более эффективны. С другой стороны, Node.js, во-первых, тоже работает весьма неплохо, а во-вторых, перед отдачей файла может совершить какие-то интеллектуальные действия, например, обратиться к базе данных, проверить, имеет ли пользователь право на доступ к данному файлу, и только если имеет, тогда уже отдавать.

Уроки React. Урок 12.

Всем привет! Сейчас мы пробежимся по нашему домашнему заданию, а также дадим важные комментарии , которые помогут Вам в дальнейшей работе с React. Для удобства Вам понабиться видеть перед собой код, поэтому перейдите на нужный commit и мы продолжим. Начнем с connect.connect нужен нам, чтобы обратиться к store. Добавим небольшую ремарку, что если Вы можете передать данные используя обычные props – передавайте. Например в containers/Articles.js мы обращаемся к store чтобы из его state достать необходимые нам статьи:

Leave a Reply