How to use/render streams with React

How to use/render streams with React

Learn how to simplify streams using/rendering with Kefir and React

TLDR;

You don’t have to be a javascript ninja to start using streams with React. The article shows a few examples demonstrating how and the component that makes it all so simple.

Streams are awesome. Everything that happens on client-side can be reduced into a stream: a stream of DOM updates, a stream of redux state changes, a stream of scrolling events, etc.

It implies that mastering streams skill is a crucial part of modern client-side engineering.

Luckily, there is a very simple way of how to use/render streams with React. And by rendering a stream I mean converting data from a stream into something visual. It can be a value like a date/time or behavior of elements on a page.

Few Examples

Let's start with a few examples, if you are short on time, then scroll to the end of the article where I’ll describe how to actually render a stream, it is pretty simple, I promise!

For streams, I’ll be using awesome Kefir library. Highly recommend it, but it is up to you which library you would prefer, it does not really matter.

Date/Time

Let’s render the date/time value that updates every second. If you ever tried that, you might remember how bulky such a simple component might look like, but with a stream, it is very simple:

import React from 'react';
import Kefir from 'kefir';
import FromStream from './FromStream';

const dateStream = Kefir.interval(1000).map(() => new Date().toString());

export default () => (
  <FromStream stream={dateStream}>
    {(dateString) => dateString}
  </FromStream>
);

Scroll

A bit more complicated example would be a component that renders a custom scroll bar.

import React from 'react';
import Kefir from 'kefir';
import FromStream from './FromStream';

const scrolledPercentStream = Kefir.fromEvents(document, 'scroll').map((e) => {
  const scrollY = window.document.pageYoffset;
  const scrollHeight = e.target.body.scrollHeight;
  return scrollY / (scrollHeight - windiw.innerHeight) * 100;
});

export default () => (
  <FromStream stream={scrolledPercentStream}>
    {(percent) => (
      <div className="bar" style={{ top: `${percent}%` }}></div>
    )}
  </FromStream>
);

Again, super simple. Here we have a simple scroll stream that mapped into a scrolled percentage stream, which then used to set top value for scroll bar cursor styles.

Animations

If you ever used a library like react-transition-group, then the code would probably look familiar to you. But the thing I like the most is that we don’t have to load additional dependency for animations, streams library and a little bit code is all we need:

import React, { PureComponent } from 'react';
import FromStream from './FromStream';

const ENTERING = 'ENTERING';
const ENTERED = 'ENTERED';
const EXITING = 'EXITING';
const EXITED = 'EXITED';

const inStates = [ENTERING, ENTERED];
const outStates = [EXITING, EXITED];

const createAnimationStream = (events, timeout) => {
  return Kefir.stream((emitter) => {
    emitter.emit(events.shift());
    const interval = setTimeout(() => {
      const nextEvent = events.shift();
      if (!nextEvent) {
        emitter.end();
      } else {
        emitter.emit(nextEvent);
      }
    }, timeout);

    return () => {
      return clearInterval(interval);
    };
  }).toProperty();
};

export default class Animate extends PureComponent {
  static defaultProps = {
    in: null,
    out: null,
    timeout: 100,
  }

  render() {
    if (this.props.in === null && this.props.out === null) {
      return this.props.children(ENTERED);
    }

    const events = this.props.in ? inStates : outStates;
    const animateStream = createAnimationStream(events, this.props.timeout);
    return (
      <FromStream stream={animateStream}>
        {this.props.children}
      </FromStream>
    );
  }
}

This is a bit longer than previous examples, but still about 20x shorter than the react-transition group lib. Of course, it has fewer features, but there is a lot of room for a few more lines of code.

FromStream component

So, let’s have a look at the FromStream component itself:

import { PureComponent } from 'react';

export default class FromStream extends PureComponent {
  constructor(props) {
    super(props);
    this.state = { value: false };
  }

  componentDidMount() {
    this.initStream();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.stream !== this.props.stream) {
      this.initStream();
    }
  }

  componentWillUnmount() {
    if (this.unSubscribe) {
      this.unSubscribe();
    }
  }


  initStream() {
    if (this.unSubscribe) {
      this.unSubscribe();
      this.unSubscribe = null;
    }

    if (this.props.stream) {
      const onValue = (value) => {
        this.setState(() => ({ value: map(value) }));
      };

      this.props.stream.onValue(onValue);
      this.unSubscribe = () => stream.offValue(onValue);
    }
  }

  render() {
    return this.props.children(this.state && this.state.value);
  }
}

Nice and simple 42 lines of code. No magic. But gives a great power to work with streams in React app.

Examples above show that sometimes streams are very helpful and with mere React component they can be very handy for rendering events data, or even for complex cases like animations.

Of course, examples are simplified for clarity and in real-world, they would probably be a bit more complicated. Not so much, though. I’ve checked how we use streams in the Holloway reader app and found that the components we use are about at the same level of complexity as examples above.

If you feel like examples from the article are not enough detailed or explained, or you have some concerns about streams + React, or you have some other thoughts, feel free to reach me out, I would love to hear your feedback!

reactjs

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

ReactJs Course | How to build a YouTube Clone using ReactJS

Hello, this is a new tutorial series about ReactJs. In this series, I will teach you two important topics. First, I will be teaching you what is ReactJs library and why this is so powerful and expandable. We will see what are the important...

Top Reasons to Choose ReactJS for Front-End Development - Prismetric

Why ReactJS is perfect choice for your next web application? Get to know all about ReactJS development and its benefits in detail for frontend development.

ReactJS Web App Development Services

We provide top-notch ReactJS development services to global clients. Hire expert ReactJS developers from top React JS development company, Skenix Infotech.

Highcharts with Reactjs

#reactjs #highcharts #therichpost https://therichpost.com/highcharts-with-reactjs-working-tutorial/ Highcharts with Reactjs Please like, share and subscribe....