Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 104 additions & 16 deletions vignettes/intro_reactR.Rmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Intro to reactR"
author: "Kent Russell"
author: "Kent Russell & Harry Anderson"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
Expand All @@ -9,30 +9,49 @@ vignette: >
%\VignetteEncoding{UTF-8}
---

## Why reactR?
## Why reactR

[`react`](https://reactjs.org/) has become incredibly popular, and the ecosystem around `react` is robust. `reactR` aims to allow `R` users to more easily incorporate `react` and `JSX`.
[`React`](https://reactjs.org/) is a JavaScript library for building user interfaces.
When developing Shiny apps, we use functions from the `{shiny}` package like `sliderInput()` and `selectInput()` to help us to easily implement common UI features in our Shiny apps.
When we build and launch our Shiny apps, the R code that we write gets compiled to HTML, CSS and JavaScript —the three key languages in web development —and these `{shiny}` UI functions render the simple HTML elements that make up the user-interface of our apps.

## Install
Most of the time, these functions will be enough to build-out our prototypes, but they are limited in what they offer, and seasoned web developers know that there's a world of UI potential beyond what `{shiny}` gives us out-of-the-box.
While packages like `[{shinydashboard}](https://github.com/rstudio/shinydashboard)` expand the libary of UI elements at our disposal, they too have their limitations.
The React ecosystem, on the other hand, has a package for every piece of UI that we could ever imagine.
Of course, working with React means working with JavaScript.
Thankfully `{reactR}` exists to bind React components to R functions, so even if we don't know JavaScript, we can still use React components in our Shiny apps.

```
install.packages("reactR")
Additionally, developers who already know JavaScript may find it more natural to create custom pieces of UI in React than directly in Shiny.
In this way, `{reactR}` makes it possible for each member of a mixed data-science/web-development team to contribute to their fullest potential on a Shiny project.

If you don't know anything about React, you may benefit from brushing-up on the basics with the [official tutorial](https://reactjs.org/tutorial/tutorial.html).
This will help you to understand the non-R syntax that you'll see in this tutorial.

## Installing reactR

```{r}
install.packages("reactR", repos = "http://cran.us.r-project.org")

# for the latest development version
# install from Github
# devtools::install_github("timelyportfolio/reactR")
```

## Quick Example

Let's use `react` to render a simple `h1` HTML element below.
## A quick example
### Rendering an H1 tag

<div id="react-heading-here"></div>
The code below will attach some JavaScript to the page.
These lines of JS will create an H1 element, and insert it at the place on the page where the div with the ID "beef" is.
The text content of the H1 will read _"Powered by React"_.

```{r}
library(reactR)
library(htmltools)
library(reactR)

div(id="beef")
```

```{r}
attachDependencies(
tags$script(
"
Expand All @@ -42,18 +61,87 @@ attachDependencies(
null,
'Powered by React'
),
document.getElementById('react-heading-here')
document.getElementById('beef')
)
"
),
html_dependency_react() # The script above depends on the React library
)
```

Obviously, rendering an H1 tag can already easily be done via `h1("Powered by React")`.
The point of the above example is to familliarize ourselves with the arcitecture of how to write React code within an R environment.
Particularly, it's important to note how we're using the `attachDependencies()` function to insert some JS into the page.

## Using JSX

JSX goes hand-in-hand with React.
It allows us to express React components as HTML-like tags.
In other words, instead of using `React.createElement(SomeReactComponent)` whenever we need to create a new element, we can simply wrap the component name in tags, `<SomeReactComponent />`, and omit the call to `React.createElement()`.

Without getting into the nitty-gritty of how to use JSX, let's simply focus on how to use JSX with reactR.

Let's create the same H1 tag as in the last example, but this time we'll do it in JSX, using the `babel_transform()` function from `{reactR}`.

```{r}
div(id="penguin")
```

Don't forget to first install the `{V8}` package, otherwise `{babel_transform()}` won't work.

```{r echo=FALSE}
install.packages("V8", repos="http://cran.us.r-project.org")
```

The code-chunk below will generate the call to `React.createElement()` for us and store it in a variable that we'll use to render the H1 in the following code chunk.

```{r}
library(stringr)

the_transformed_jsx <-
babel_transform("ReactDOM.render(
<h1>Powered by React</h1>,
document.getElementById('penguin'))")

the_transformed_jsx
```

Now that we have the transformed string of JavaScript code, we can attach it to our document, as shown below:

```{r}
attachDependencies(
tags$script(the_transformed_jsx),
html_dependency_react()
)
```

## Blog Post
> Hopefully, in the future, we can convince RStudio to modify `htmltools` to work directly with `JSX` (see [issue](https://github.com/rstudio/htmltools/pull/72)).

For more on how we can use R and React, see the blog post [React in R](https://www.jsinr.me/2017/11/19/react-in-r/). Also, there are many more examples in the Github repo at [inst/examples](https://github.com/react-R/reactR/tree/master/inst/examples).
## The bigger picture

## Using JSX
While it is possible to use `{reactR}` to write JSX and React code directly inside of R code, doing so is __currently__ limited, and you will likely encounter numerous hurdles when trying to use state, or even include someone else's component in your code.

Where `{reactR}` really shines though, is when you use it to create HTML widgets and custom Shiny inputs.

For example, if you wanted to use a time-picker input in your Shiny app (like the one below), you could create one using the functions that reactR provides.

![](./time_picker.gif)

The article titled [Authoring inputs powered by React with reactR](https://react-r.github.io/reactR/articles/intro_inputs.html) will walk you through how to take a React component from an NPM package, and package it into a custom Shiny input.

Similarly, if Shiny isn't your bag, you can package React code as a custom HTML Widget.
For that, [Authoring htmlwidgets powered by React with reactR](https://react-r.github.io/reactR/articles/intro_htmlwidgets.html) will be your guide.

> NPM stands for "Node Package Manager", and it is the package registry where you can find most React packages.
> Think of it like CRAN, for React.

In addition to the articeles mentioned above, the resources below will help you to get on your way to integrating React in your R projects:

* [Video: Integrating React.js and Shiny](https://rstudio.com/resources/rstudioconf-2019/integrating-react-js-and-shiny/)
* [Blog post: React in R](https://www.jsinr.me/2017/11/19/react-in-r/)

You can also find more examples of reactR at work in the Github repo at [inst/examples](https://github.com/react-R/reactR/tree/master/inst/examples).

[`JSX`](https://reactjs.org/docs/jsx-in-depth.html) helps ease some of the burden caused by `React.createElement`. `reactR` provides a `babel_transform()` function to use `JSX`. Hopefully, in the future, we can convince RStudio to modify `htmltools` to work directly with `JSX` (see [issue](https://github.com/rstudio/htmltools/pull/72)).
React is a very useful tool for composing complex UIs, and the reactR package makes the power of React available to R users.
This makes it even more possible to have software engineers and data scientists collaborate on the same production applications, leveraging the expertise of each to create better tools for their communities.
We think this package has huge potential, and we hope that you will too.
Binary file added vignettes/time_picker.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.