Комментарии 26
У вас в примерах используются декораторы, хотя можно написать тоже самое обычными функциями. Вот ссылка на официальную позицию по поводу декораторов и react. Да и в целом, чем меньше экзотики в документации, тем лучше.
А можно аргументацию чем это плохо?:)
+1, я даже и не заметил, что там используется bind-оператор.
Конечно, как и с декораторами, лучше по возможности показывать примеры с минимум синтаксического сахара.
Еще не очень понятно зачем rxConnect знает про redux store.
Можно же использовать redux-connect и rx-connect вместе
function MyComponent({value}) {}
const mapStateToProps = state => {user: state.user};
const mapObservable = props$ => {
const user$ = props$.pluck("user").distinctUntilChanged();
return Rx.Observable.merge(
Rx.Observable::ofActions({
logout: props$.logout
}),
user$.map(user => ({ user })),
);
}
connect(mapStateToProps, {logout})(rxConnect(mapObservable)(MyComponent));
connect
сложит все необходимые данные и действия в props, откуда их сможет достать rxConnect. И не нужно лазить в контекст и зависеть от деталей реализации react-redux.
Redux-Observable — это middleware, в то время как RxConnect — это Higher Order Component для написания реактивных компонент. Причём никто не мешает использовать оба — Redux-Observable для обработки глобальных action-ов и RxConnect чтобы состояние связывать с компонентом и обработки локального состояния
По теме, у нас как раз одной из целей идет внедрение Rx, так что ты как нельзя вовремя.
Решение отличное, но первое, что бросается в глаза — ручная сборка/разборка ключей (угу, тот самый $). Неубедительно как-то.
Но, как уже упомянули выше, очевидно напрашивается отрезание redux-логики, что даст возможность считать все входные ключи в декораторе за стримы без дополнительной фильтрации.
Стучись в скайп ( bsideup ) если будут вопросы :)
Ручная сборка\разборка ключей? о_О Чё то я не понял, можешь пояснить? Вроде как минимум ручного в либе :)
так… это ж… фича! :D
Суть в том, что ты объявляешь Subject search$, а в компонент придёт search = (...args) => search$.onNext(args)
, т.е. это не 1 к 1.
Ну правда, указываю search — приходит search, вроде проще некуда ) ну а если нужно указать тип, то для этого лучше взять ts/flow
причём тут тип то? о_О это вообще не про типизацию :D
https://github.com/bsideup/rx-connect/blob/master/src/mapActionCreators.js#L3-L21
может этот блок кода объяснит :)
Сам говоришь, что наличие $ — это соглашение в Rx, то есть «своего рода тип», и я тут действительно не про типизацию.
Я к тому, что не вижу наличие еще одного контракта действительно оправданным. Ну, т.е. на текущий момент, этот доллар нужен для отделения обычных пропсов от стримов и, как следствие, различной их обработки. Но ведь если не хэндлить все пропсы в rx-connect, а отдать это редаксу, то это доллары станут не нужны.
Либо я упускаю из виду какую-то основную идею, либо просто не люблю доллары :D
Код погонять сейчас нет возможности.
Если писать без долларов, то тогда тот же самый код будет выглядеть примерно так:
@rxConnect(() => {
const search = new Rx.Subject();
const articles$ = search
.pluck(0) // нас интересует первый переданный аргумент
.flatMapLatest(searchWikipedia)
return Rx.Observable.merge(
Rx.Observable.of({ search: (...args) => search.onNext(args) }),
articles$.map(articles => ({ articles }))
)
})
что имхо гораздо грязней
Вот только появилась другая проблема — стало сложно делать простые вещи, а каждый чих (такой как поле ввода логина) должен проходить через action creator-ы, reducer-ы, и храниться в глобальном состоянии.
Можно просто изначально использовать mobx и всё. Никаких проблем нет — код проще, обновления компонентов атомарнее.
Можно же переложить локальный стейт в стор редакса, и не будет изначальной проблемы.
RxConnect — когда React встречает RxJS