The best, most maintainable code, is code that matches the way you think about the problem, without a lot of noise
What do I mean by noise...?
Therefore, the best
Language / Framework / Library
FOR YOU
is the one that either:
A. Matches your way of thinking
B. Guides you to think in a different way
Succinct, expressive code, that lets you build complex web applications
"without a lot of noise"
useState()
useEffect()
const [state, setState] = useState()
useEffect(() => {
const sub = observable$.subscribe(
newState => setState( newState )
);
return () => sub.unsubscribe()
}, [])
Syncing State
const [people, setPeople] = useState();
useEffect(() => {
const sub = ajax(ENDPOINT).subscribe(
({ response: { results } }) => {
setPeople(results);
}
);
return () => sub.unsubscribe();
}, []);
RxJS.ajax()
const people = useSelector(
state => state.people
)
const dispatch = useDispatch()
useEffect(() => {
dispatch({ type: FETCH_PEOPLE })
}, [])
Redux fetch
const [people, setPeople] = useState();
useEffect(() => {
cosnt url = ENDPOINT + `?filter=${filtertext}`
const sub = ajax(url).subscribe(
({ response: { results } }) => {
setPeople(results);
}
);
return () => sub.unsubscribe();
}, [ filtertext ]);
Prop Changes
const [events, setEvents] = useState();
useEffect(() => {
const sub = calendar$.pipe(
map(calendar => calendar.events),
distinctUntilChanged()
).subscribe(setEvents);
return () => sub.unsubscribe();
}, []);
Perf
Separation of Concerns
// The same in every component
const [state, setState] = useState()
useEffect(() => {
const sub = state$.subscribe(
newState => setState( newState )
);
return () => sub.unsubscribe()
}, [])
const useObservable = fn => {
const [state, setState] = useState()
const state$ = useRef(new BehaviorSubject()).current
const actions$ = useRef(new Subject()).current
const newState$ = useRef(fn(actions$, state$)).current
const dispatch = action => actions$.next(action)
useEffect(() => {
const subscription = newState$
.subscribe(newState => setState(newState))
return () => subscription.unsubscribe()
}, [newState$])
return [state, dispatch]
}
useObservable
const MyComponent() {
const [count, dispatch] = useObservable(
(actions$, state$) => {
actions$.pipe(
combineWithLatest(state$),
switchMap(([,n]) =>
ajax(endpoint(n + 1)).pipe(
map(response => respose.result)
)
)
)
}
);
return (
<button onClick={e => dispatch(e.target.value)}>
{count}
</button>
);
}
useObservable
const Container = (props) => {
const [state, dispatch] = useObservable(myEpic);
const handleChange(e => dispatch({
type: 'CHANGE',
payload: e.target.value
}));
return (
<Presentational {...state}
onChange={handleChange}
/>
);
}
A new container
RxJS is super popular across frameworks so, sometimes we get to use solutions from other communities, and there is just a lot of cool RxJS stuff out there
<$> React RxJS Elements
https://github.com/kosich/react-rxjs-elements
React-RxJS
https://react-rxjs.org/
RxJS State
https://github.com/BioPhoton/rxjs-state
Rx-Handler https://github.com/johnlindquist/rx-handler
Sanity.io
https://www.sanity.io/docs/client-libraries/js-client
Rx Visualizer
https://rxviz.com