Комментарии 31
Ну, понеслась!
На ангуляре точно так же — разобрались с темплейтами и поехали. DI вас использовать никто не заставляет, особенности change detection'а проблем не доставят (если выполнять пару правил — точно тех же, к слову, как и в реакте :))
Что там еще подкапотного остается?
Как рендерится Реакт:
const myElement = React.createElement(MyElement)
const appNode = document.getElementById('my-app')
ReactDOM.render(myElement, appNode)
мы выдаем Реакту DOM-ноду, он выводит в нее свой контент. Все просто и понятно.
Как рендерится Angular:
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule)
Что здесь происходит? Куда в итоге Angular отрендерит контент? Что делать, если на странице одновременно два приложения? Ничего не понятно.
Возможно, на это можно найти ответы в документации, но подкапотной магии тут немало.
React — все же по сути шаблонизатор. И за счет этого его гораздо проще понять. Он просто рендерит компонент. Все, точка. Причем все компоненты не связаны друг с другом и им плевать друг на друга.
В ангуляре очень большая связанность, на мой взгляд (я работал только с первым правда, но там ад вообще), и именно это порождает тонну проблем вида «боремся с фреймворком».
Этот код не эквивалентен коду на реакте. Эквивалентный код в ангуляре написать нельзя: ангуляр ничего не знает о дом и браузере. По-этому вы не можете ни создать дом-ноду, ни отрендерить ее в дом-ноду (при запуске, например, на декстопе, вне браузера, никакого дома может не быть, по--этому можно считать, что его по факту и нет).
Прошу прощения, вместо слова "рендерится" надо было использовать слово "инициализируется".
Оба фрагмента кода эквивалентны: они инициализируют корневой компонент вашего приложения.
Ну в ангуляре это не так. В ангуляре ваш код инициализирует модуль, а рендер директив — побочный эффект. Все компоненты модуля рендерятся в местах, в которых расположены их селекторы (если для компоненты указан селектор) — это стандартное поведение компоненты. Для удобства при инициализации модуля это поведение блокируется для всех компонент, не указанных в рутах. У вас просто ментальная модель неправильная.
PS. raveclassic Понеслась!)
Всё зависит от амбиций. Если хочется писать меньше, а делать больше, то ставка ставится на какой-либо фреймворк, где всё уже продумано/написано более компетентными ребятами (Angular, например, а то и ExtJS). Если хочется чувствовать себя крутым (и зарабатывать соответственно), то велосипедят на самых модных технологиях и инструментах (сейчас это React+Redux+Babel+WebPack).
Любой фреймворк с централизованной документацией проще в старте, чем десяток библиотек и сотня статей как их подружить, разбросанных по всем интернетам.
В чём сила Redux?
Статьи про редакс для новичков — это как типичный неудачный форсед-мем. Всем уже тошно от одного заголовка, а они все лезут и лезут.
Тогда Redux with Ramda вам точно должно понравиться ;]
Ответа на вопрос "в чем сила" так и не прочитал. Сказано что 1) Redux сложный 2) неимоверно крутой (без объяснений) 3) никто его не понимает 4) у него скудный неудобный API 5) был придуман time-travel и всякий мидл-вар в нем удобен. В чем сила так и не раскрыто.
По сути, единственная проблема, которую решает Redux — это проблема "эталонной версии данных", когда из множества источников изменений нужно получить один непротиворечивый "стейт" для формирования текущего "вью". Эффективных решений у этой проблемы может быть сотня, но Redux (а точнее Flux) — это решение хоть как-то формализует и позволяет неопытным разработчикам не наступать на грабли (но делает это не всегда оптимальным образом, это не "серебряная пуля"). Еще ни разу не встречал статей про Redux, где об этом было бы сказано простым языком: все постоянно сбиваются в какую-то малопонятную и ненужную заумь, как и в этой статье.
Новички хоть с редуксом, хоть без, ходят по одним и тем же граблям. Например, заводят по отдельной ветке в редуксе для каждой страницы. В итоге изменения, сделанные на одной странице, не видны на другой до перезагрузки данных с сервера.
Наверное, в широком смысле можно сказать, что и СУБД с неблокирующим select (точно знаю, что есть в Oracle) тоже решают похожую проблему, и для этого тоже используется некая реализация версионирования данных, когда каждому SCN (system change number) ставится в соответствие определенное состояние данных в базе.
Интересно наблюдать, как очень похожие инженерные решения переизобретаются в индустрии там и тут в разных видах.
У меня с Redux вышло как с Angular 1 в свое время. Почитал, вроде красиво, но что-то отталкивает. После огромного роста популярности возникает мысль, что может я старею и пора переучиваться? Пробую на парочке простых проектов, попутно лучше разбираясь с идеологией. Приложения работают, после пары крупных рефакторингов даже код смотрится хорошо, но большой симпатии к инструменту так и не возникает. Angular 1 был заменен на React, который меня очень радует. Вместо Redux часто прибегаю к mobx, но не могу сказать, что он меня полностью устраивает.
Я пришёл к такому разделению редюсеров. Есть общий редюсер app, где свалка глобальных состояний приложения. Для каждой сущности два редюсера: item и list. При этом редюсер для item используется на нескольких страницах (просмотр и редактирование сущности). При этом данные отображаемых сущностей в списке (list) спрятаны в локальных стейтах, а в редюсерах живут флаги и сайд-эффекты. И только данные для item так же живут в редюсере, потому что их нужно отображать в форме и в превью (например). Благодаря redux-act, ни один switch не пострадал.
// @flow
import { createAction, createReducer } from 'redux-act'
import api from 'api'
export const REDUCER = 'user'
const NS = `@@${REDUCER}/`
const reset = createAction(`${NS}RESET`)
const set = createAction(`${NS}SET`)
export const readItem = (id: ?number) => (dispatch: Function, getState: Function) => {
if (id) {
return api.get(`/api.php/members/${id}`).then(response =>
dispatch(set(response.data))
)
}
dispatch(reset())
return Promise.resolve()
}
export const submit = (id: ?number, values: Object) => (dispatch: Function, getState: Function) => {
if (id) {
return api.put(`/api.php/members/${id}`, values)
}
return api.post(`/api.php/members`, values)
}
const initialState = {}
export default createReducer(
{
[reset]: () => ({ ...initialState }),
[set]: (state, data) => ({ ...state, ...data }),
},
initialState,
)
В чём сила Redux?