Use React

for Great Good

SPA frameworks

MVC

MVVM

MVW

Model

 

  • how do I get from state A to state B
  • and from state B to state D
  • and from state A to state C
  • and from state D back to state B?

Mutation

React - View

Encourage immutability

# hello_world.cjsx

module.exports = React.createClass
  displayName: 'HelloWorld'

  render: ->
    <div className="hello">Hello world!</div>


# usage

HelloWorld = require('./hello_world')

React.render(<HelloWorld />, document.body)

React components

# hello_world.cjsx

module.exports = React.createClass
  displayName: 'HelloWorld'

  render: ->
    React.DOM.div { className: 'hello' }, [
      'Hello world!'
    ]


# usage

HelloWorld = require('./hello_world')

React.render(<HelloWorld />, document.body)
render: ->
  <ActionButton text="Do this" onAction={this.handleAction} />

handleAction: ->
  # (...) 
React.createClass
  displayName: 'ActionButton'

  propTypes: 
    text: React.PropTypes.node.isRequired,
    onAction: React.PropTypes.func.isRequired

  render: ->
    <button onClick={this.props.onAction}>{this.props.text}</button>
React.createClass
  displayName: 'Counter'

  getInitialState: ->
    count: 0

  render: ->
    <div>
      <span className="count">{this.state.count}</span>
      <ActionButton text="+1" onAction={this.increaseCounter} />
      <ActionButton text="-1" onAction={this.decreaseCounter} />
    </div>

  increaseCounter: ->
    @setState count: @state.count + 1

  decreaseCounter: ->
    @setState count: @state.count - 1

Keeping state

AJAX?

Yes, please!

ApiStateComponent =

  componentDidMount: ->
    @loadJSON()

  loadJSON: ->
    $.get(@endpoint).then(@setState)
  

Mixins

# [
#   {
#     name: 'Wrocław',
#     description: 'Beautiful city'
#   }
# ]

React.createClass
  displayName: 'Cities'

  mixins: [ApiStateComponent]

  endpoint: 'http://localhost:3000/cities.json'

  render: ->
    <div>
      {@cities()}
    </div>

  cities: ->
    @state.cities.map (city) ->
      <dl>
        <dt>{city.name}</dt>
        <dd>{city.description}</dd>
      </dl>

Let's code!

React and Rails

 

gem 'sprockets-coffee-react'

Isomorphism

https://medium.com/@olance/isomorphic-reactjs-app-with-ruby-on-rails-part-1-server-side-rendering-8438bbb1ea1c

Flux

 

Testing

jest.dontMock('../CheckboxWithLabel.js');
describe('CheckboxWithLabel', function() {
  it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('../CheckboxWithLabel.js');
    var TestUtils = React.addons.TestUtils;

    // Render a checkbox with label in the document
    var checkbox = TestUtils.renderIntoDocument(
      <CheckboxWithLabel labelOn="On" labelOff="Off" />
    );

    // Verify that it's Off by default
    var label = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'label');
    expect(label.getDOMNode().textContent).toEqual('Off');

    // Simulate a click and verify that it is now On
    var input = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'input');
    TestUtils.Simulate.change(input);
    expect(label.getDOMNode().textContent).toEqual('On');
  });
});

React Native

React.createClass

  renderRow: (file) ->
    <View>
      <TouchableHighlight onPress={@selectModel(file)} underlayColor='rgba(0, 0, 0, .6)' />
      <Text style={{ height: 30, color: 'white' }}>{file}</Text>
    </View>
    
  render: function() {
    source = @getDataSource(@props.files);

    <ListView style={{ flex: 1 }} renderRow={@renderRow} dataSource={source} />

Links

Thanks!

deck

By Lucjan Suski

deck

  • 441