Slide 1

Slide 1 text

REACT ON RAILS David Anguita <3 CiudadReal.rb

Slide 2

Slide 2 text

Hi, I'm @danguita

Slide 3

Slide 3 text

The UI as a first-class citizen

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Why React?

Slide 6

Slide 6 text

Library for building user interfaces

Slide 7

Slide 7 text

Who is behind React?

Slide 8

Slide 8 text

The V in MVC ● It's a library, not a framework ● Excellent for managing UIs with data that changes over time ● Makes no assumptions about the rest of your stack ● Runs entirely on the client

Slide 9

Slide 9 text

Can be adopted gradually

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

React basics ● Based in components ● Component lifecycle ● Props and State ● Virtual DOM

Slide 12

Slide 12 text

class Greeting extends React.Component { handleClick() { alert(`Hey, ${this.props.name}`); } render() { return ( Click me ) } }

Slide 13

Slide 13 text

Slide 14

Slide 14 text

class Greeting extends React.Component { constructor(props) { super(props); this.state = { name: 'Unknown' }; } handleClick() { this.setState({ name: this.props.name }); } render() { return (
Name: {this.state.name}
Click me
) } }

Slide 15

Slide 15 text

Short learning curve

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

We have come here to talk about Rails!

Slide 18

Slide 18 text

REACT ON RAILS David Anguita <3 CiudadReal.rb

Slide 19

Slide 19 text

Integration approaches

Slide 20

Slide 20 text

● Easy to use for Rails developers, especially with legacy code ● JSX compilation in the asset pipeline ● Render components into Views via helpers ● Component generator The react-rails gem

Slide 21

Slide 21 text

● Data are passed to React components directly from Rails Controllers ● Rails Controllers are for routing and retrieving data ● Rails Views are for mounting components and passing data to them ● Good starting point since it is just replacing the View ● There's room for improvement in terms of architecture Rails front-end, retrieving data in the server 1

Slide 22

Slide 22 text

# app/controllers/posts_controller.rb def show @post = Post.find(params[:id]) end # app/views/posts/show.html.erb = react_component("Post", post: @post) # app/assets/javascripts/components/post.es6.jsx class Post extends React.Component { render() { return (
Title: {this.props.post.title}
Body: {this.props.post.body}
) } }

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

● The front-end can now be virtually isolated from the back-end ● The back-end is providing a well-defined API ● We still have Rails Controllers for routing and Views for mounting components ● Slightly better approach in terms of architecture ● Not leaving the comfort of Rails Rails front-end, retrieving data in the client 2

Slide 25

Slide 25 text

# app/views/posts/show.html.erb = react_component("Post", postId: params[:id]) # app/assets/javascripts/components/post.es6.jsx class Post extends React.Component { componentDidMount() { this.setState({ post: this.findPostById(this.props.postId) }); } render() { return (
Title: {this.state.post.title}
Body: {this.state.post.body}
) } }

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Should we stop here?

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

● Front-end and back-end are separate applications ● The back-end is just a stateless API ● The front-end is a static bundle of code consuming those well-defined APIs ● Separation of concerns ● Easier to test in isolation ● Having two applications may require separate development cycles Standalone front-end app + API-only back-end 3

Slide 30

Slide 30 text

How does it look like?

Slide 31

Slide 31 text

back-end front-end ├── config | ├── ... ├── node_modules | ├── ... ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src ├── App.js ├── PlanetItem.js ├── PlanetList.js └── index.js $ curl http://swapi.co/api/planets/ [ { "name": "Alderaan", "rotation_period": "24", "orbital_period": "364" }, { "name": "Yavin IV", "rotation_period": "24", "orbital_period": "4818" }, ... ]

Slide 32

Slide 32 text

class PlanetList extends React.Component { componentDidMount() { this.fetchPlanets(); } fetchPlanets() { fetch("http://swapi.co/api/planets/") .then(function(res) { return res.json(); }).then(function(json) { this.setState({ planets: json.results }); }.bind(this)); } render() { return (
{this.state.planets.map(function(planet, index) { return ( ) })}
); } }

Slide 33

Slide 33 text

class PlanetItem extends React.Component { render() { return (

{this.props.planet.name}

Rotation period: {this.props.planet.rotation_period}

Orbital period: {this.props.planet.orbital_period}

); } }

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Benefits of having a API-only back-end ● There could be multiple clients hitting exactly the same back-end ● The technology behind the interface is replaceable ● It is not dealing with Views logic or HTML rendering ● It is focused on data representation

Slide 37

Slide 37 text

Benefits of having a standalone front-end ● Easy delivery ● Separate development cycle ● The front-end application itself is replaceable ● It is focused on user interactions

Slide 38

Slide 38 text

Drawbacks of having a standalone front-end ● Limited client-side performance ● Limited browser compatibility ● The UI initialization may be delayed in slow Internet connections ● Higher level of complexity

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

First do it, then do it right, then do it better

Slide 41

Slide 41 text

Thank you

Slide 42

Slide 42 text

Questions?

Slide 43

Slide 43 text

CiudadReal.rb, October 2016