Skip to content

Instantly share code, notes, and snippets.

@marcusradell
Last active January 12, 2017 21:11
Show Gist options
  • Save marcusradell/f4381234e2389537d2c15f7ec9113e02 to your computer and use it in GitHub Desktop.
Save marcusradell/f4381234e2389537d2c15f7ec9113e02 to your computer and use it in GitHub Desktop.

Observable components with React

Bring the fresh feel of React to the rest of your code

Abstract

From the Redux docs about Rx (http://redux.js.org/docs/introduction/PriorArt.html)

The question is: do you really need Redux if you already use Rx? Maybe not. It's not hard to re-implement Redux in Rx. Some say it's a two-liner using Rx .scan() method. It may very well be! [...] Let us know how it goes!

After a comparison between Redux and RxJS, I chose RxJS, and tried to follow along with how redux worked. About a year later, I'm ready to tell you how it went.

In this session, I will use most.js instead of RxJS as my reactive library.

Target audience

  • You should be somewhat familiar with JavaScript's map/filter/reduce functions.
  • React and Redux knowledge is a plus.
  • No previous experience of reactive programming will be presumed. We will not go in-depth into the semantics of the reactive tools and APIs. We will learn by example instead and discuss the solutions.

What you might hope to learn

  • Create reusable reactive components
  • Basic unit test actions and streams (no fancy reactive scheduler stuff)
  • Hook up Observables with React
  • Compose components

What I hope to inspire you to

We will not use or build a framework!

Build anything you want. Build anything you need. This time you can break the rules before they break you!

Part 0 (Basic): Prebaked

We go through how to setup a new laboration environment quickly.

Create-react-app

Fast way to get started with new React environments without getting stuck on webpack.

Follow instructions on: https://github.com/facebookincubator/create-react-app

React-storybook

Fast way to setup a view over all of your components.

Follow instructions on: https://github.com/storybooks/react-storybook

Source code

Current source code is an ongoing live project. Code might change (have changed) in the future. git clone and yarn/npm install: https://github.com/marcusnielsen/reactive-tournament

Summary

Installing without previous knowledge will take about 15 mins.

Part 1 (Basic): Button component

We create a stateless component with action press.

Creating actions

We look at a src/components/button/actions.js and its tests. https://github.com/marcusnielsen/reactive-tournament/blob/development/src/components/button/actions.js

Note on Subjects

Subjects lets you produce an event from anywhere.

Prefer using a regular Observable as the default solution and always motivate the usage of Subjects.

We use Subjects as we want to be decoupled from our event producers. All this means is that when you gain knowledge, you can choose the same or differently.

Adding a view

We keep our component model separate from the view by injecting the model into our viewable component. We bind the press action with our pure render function and try it out in our react storybook.

Part 2 (Basic): Input component

A stateful component that sets a text value.

Adding state

We map our setValue action stream into reducers in input/state.js and merge them into a scan stream that emits a new state for every action, starting with a default state. We will point out the similarities with both React's setState function and Redux's reducer functions.

Interopting with react stateful API

We need to hand over our reactive state to React. This means that we need to leave the reactive domain and enter the imperative world at some point and hand the state to React.

The first choice would be to combine child states up to one single state tree and distribute it downwards again via props. The second choice would be to subscribe to the component's own state stream in React's componentWillMount. Both choices have pros and cons, and I will explain the main points of why I think the second choice is a bit more reactive.

We create a helper util that wraps our pure render functions in a stateful react component.

Part 3 (Basic): Building a form component

Enhancing the input component

We add two buttons to the input component to save and cancel input values. We make our buttons viewable in our input's viewable-factory and discuss benefits from separating the model from the view. We show how the view isolates the actions while the button model still exposes the actions to the parent.

Create a form component

We build a stateless form component that consists of multiple input fields with isolated states.

Extra Part A (Medium): Basic Router component with epics

We implement the hamburger-pattern in router/epics.js where a side-effect is produced by a stream and triggers a response stream. We inject an incoming side-effect as a stream and an outgoing as a callback function. We add a pages object where each page is a set of components.

TODO: Create subchapters

Extra Part B (Advanced): Server-data store and basic dependency injection

We create a reusable single-source-of-truth CRUD store to communicate with a server API. We inject a websocket client as an event producer. We add localstorage and hydrate our stores with the persisted state on browser reload. We revisit the input component and add epics for saved values.

TODO: Create subchapters

Extra Part C (Advanced): Handling dynamic sets of children

This will be a usecase for flatMap. It also shows how creating entire components with actions is still serializable and perssistable. Overkill for most settings except crowds who are already into reactive programming.

TODO: Create subchapters

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