Skip to content

Conversation

@kosich
Copy link
Owner

@kosich kosich commented Apr 19, 2021

Intro

This feature introduces a reactive components style (like it Recks) with React's hook API available:

let Component = createComponent$((props$: Observable<SomeProps>) => {
  // this function initialises component and is called only once
  // so it's a good place to declare callbacks
  let onClick = () => alert('Wow! Clicked!');

  // or use hooks
  let contextData$: Observable<any> = useHook$(() => {
    // call one or many hooks here
    return useContext(SOME_CONTEXT);
  });

  // and we return either JSX or a stream of JSX (Observable<JSX>)
  return <div>
    <$>{
      // and we can still use <$> elements to display dynamic data
      props$.pipe(map(p => p.id))
    }</$>
    <button onClick={ onClick }>click me</button>
  </div>
})

Here's an example using react-router useParams hook with data fetching:

import { switchMap } from 'rxjs/operators';
import { useParams } from 'react-router-dom';
import { $, createComponent$, useHook$ } from 'react-rxjs-elements';

// create a component for route /page/:id
export default createComponent$(() => {
  // get route params as a stream
  let params$ = useHook$(useParams);

  // map it to data fetching from some web API
  let data$ = params$.pipe(
    switchMap(p => fetch('/api/' + p.id))
  );

  // here we can either return a stream of JSX
  return data$.pipe(map(d => <h1>{ d.title }</h1>));
  // or display our data in a $ element
  return <$h1>{ data$.pipe(map(d => <h1>{ d.title })) }</$h1>
})

And here's a small app, made with createComponent$: https://stackblitz.com/edit/react-rxjs-elements-components-alpha

API

react-rxjs-elements now additionaly exposes:

  • createComponent$(fn: (props$: Observable<Props>) => JSX | Observable<JSX>) -- create a stream component
  • useHook$(fn: () => any)-- use a React hook (or any 3rdparty hook) inside a stream component
  • useMount$() and useUnmount$() -- both return : Observable<void>. Predefined hooks that will emit a void value when the component is mounted and unmounted

Try it

This feature is available in the @next version of this library and currently can be tried via npm i react-rxjs-elements@next or at stackblitz playground online.

Please, share your thoughts and feedback in this thread -- this helps a lot!

Have a good day :)

@kosich
Copy link
Owner Author

kosich commented Apr 27, 2021

NOTE: props$ should have a .current property, so that instead of

let Comp = createComponent$(props$ => {
  let handler = props$
  .pipe(
    map(() => () => {
      // ... do other stuff
      // then call something from current props$
      props.current.onClick();
    }}
  )

  return <$button onClick={ handler }/>
});

We could do:

let Comp = createComponent$(props$ => {
  let handler = () => {
    // ... do other stuff
    // then call something from current props$
    props.current.onClick();
  };

  return <button onClick={ handler }/>
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants