Git Product home page Git Product logo

react-dart's Introduction

#Dart wrapper library for facebook/react

##Getting started

If you are not familiar with React library read react tutorial first.

To integrate in Dart project add dependency react to pubspec.yaml.

Include native react library (provided with this library for compatibility reasons) to index.html and create element where you'll mount the react component you'll create.

<html>
  <head>
    <script async src="packages/react/react.js"></script>
    <script async type="application/dart" src="your_app_name.dart"></script>
    <script async src="packages/browser/dart.js"></script>
  </head>
  <body>
    <div id="content">Here will be react content</div>
  </body>
</html>

Initialize React in our Dart application. Mount simple component into '#content' div.

import 'dart:html';
import 'package:react/react_client.dart' as reactClient;
import 'package:react/react.dart';

main() {
  //this should be called once at the begging of application
  reactClient.setClientConfiguration();
  var component = div({}, "Hello world!");
  render(component, querySelector('#content'));
}

Inverse method to rendering component is unmountComponentAtNode

  unmountComponentAtNode(querySelector('#content'));

##Using browser native elements

If you are familiar with React (without JSX extension) React-dart shouldn't surprise you much. All elements are defined as functions that take props as first argument and children as optional second argument. props should implement Map and children is either one React element or List with multiple elements.

div({"className": "somehing"}, [
  h1({"style": {"height": "20px"}}, "Headline"),
  a({"href":"something.com"}, "Something"),
  "Some text"
])

For event handlers you must provide function that take SyntheticEvent (defined in this library).

div({"onClick": (SyntheticMouseEvent e) => print(e)})

##Defining custom elements

Define custom class that extends Component and implements at least render.

import 'package:react/react.dart';
class MyComponent extends Component {
  render() => div({}, "MyComponent");
}

Register this class so React can recognize it.

var myComponent = registerComponent(() => new MyComponent());

Use this registered component similarly as native elements.

render(myComponent({}), querySelector('#content'));
// or
div({}, [
  myComponent({})
])

Warning: registerComponent should be called only once per component and lifetime of application.

Custom element with props

var myComponent = registerComponent(() => new MyComponent());
class MyComponent extends Component {
  render() => div({}, props['text']);
}
myComponent({"text":"Somehting"})

####Creating components with richer interface than just props and children and with type control

typedef MyComponentType({String headline, String text});

var _myComponent = registerComponent(() => new MyComponent())

MyComponentType myComponent = ({headline, text}) =>
    _myComponent({'headline':headline, 'text':text});

class MyComponent extends Component {
  get headline => props['headline'];
  get text => props['text'];
  render() =>
    div({},[
      h1({}, headline),
      span({}, text),
    ]);
}
void main() {
  reactClient.setClientConfiguration();
  render(
    myComponent(headline: "My custom headline",
                text: "My custom text"),
    querySelector('#content')
  );
}

Using refs and findDOMNode

Proper usage of refs here is a little bit different from usage in react. You can specify a ref name in component props and then call ref method to get the referenced element. Return value for dart components and for javascript components is different. For dart component, you get an instance of dart class of the component. For js components (like DOM elements), you get instance of jsObject representing the react component. If you want to work with DOM nodes instead of a component, you can call top level method findDOMNode on anything the ref returns.

var DartComponent = registerComponent(() => new _DartComponent());
class _DartComponent extends Component {
  var someData = 11;
  render() => div({});
}
var ParentComponent = registerComponent(() => new _ParentComponent());
class _ParentComponent extends Component {
  render() =>
    div({},[
      input({"ref": "input"}),
      DartComponent({"ref": "dart"})
    ]);
  componentDidMount(root) {
    var inputRef = ref("input"); //return react jsObject
    InputElement input = findDOMNode(inputRef); // return InputElement in dom
    
    _DartComponent dartRef = ref("dart"); //return instance of _DartComponent
    dartRef.someData; // you can call methods or get values from it
    findDOMNode(dartRef); //return div element rendered from _DartComponent
    
    findDOMNode(this); //return root dom element rendered from this component
  }
}

Geocodes Example

For more robust example take a look at example/geocodes/geocodes.dart.

Life-cycle methods of a component

These are quite similar to React life-cycle methods, so refer to React tutorial for further explanation/spec. Their signatures in Dart are as:

class MyComponent extends Component {
  void componentWillMount() {}
  void componentDidMount(/*DOMElement*/rootNode) {}
  void componentWillReceiveProps(newProps) {}
  bool shouldComponentUpdate(nextProps, nextState) => true;
  void componentWillUpdate(nextProps, nextState) {}
  void componentDidUpdate(prevProps, prevState, /*DOMElement */ rootNode) {}
  void componentWillUnmount() {}
  Map getInitialState() => {};
  Map getDefaultProps() => {};
  render() => div({}, props['text']);
}

Testing using React Test Utilities

lib/react_test_utils.dart is a Dart wrapper for the React TestUtils library allowing for tests to be made for React components in Dart.

Here is an example of how to use React TestUtils within a Dart test.

import 'package:unittest/unittest.dart';
import 'package:react/react.dart' as react;
import 'package:react/react_client.dart' as reactClient;
import 'package:react/react_test_utils.dart' as reactTestUtils;

class MyTestComponent extends react.Component {
  getInitialState() => {'text': 'testing...'};
  render() {
    return react.div({}, [
        react.button({'onClick': (e) => setState({'text': 'success'})}),
        react.span({'className': 'spanText'}, state['text'])
    ]);
  }
}

var myTestComponent = react.registerComponent(() => new MyTestComponent());

void main() {
  reactClient.setClientConfiguration();

  test('should click button and set span text to "success"', () {
    var component = reactTestUtils.renderIntoDocument(myTestComponent({}));

    // Find button using tag name
    var buttonElement = reactTestUtils.findRenderedDOMComponentWithTag(
        component, 'button');

    // Find span using class name
    var spanElement = reactTestUtils.findRenderedDOMComponentWithClass(
        component, 'spanText');

    var buttonNode = reactTestUtils.getDomNode(buttonElement);
    var spanNode = reactTestUtils.getDomNode(spanElement);

    // Span text should equal the initial state
    expect(spanNode.text, equals('testing...'));

    // Click the button and trigger the onClick event
    reactTestUtils.Simulate.click(buttonNode);

    // Span text should change to 'success'
    expect(spanNode.text, equals('success'));
  });
}

To test the Dart wrapper, take a look at test/react_test_utils_test.dart.

react-dart's People

Contributors

hleumas avatar tomaskulich avatar matystl avatar greglittlefield-wf avatar danschultz avatar syslo avatar brandys11 avatar trentgrover-wf avatar jurom avatar tosh avatar jayudey-wf avatar cornedor avatar janamou avatar maxwellclarke-wf avatar grumpy avatar travissanderson-wf avatar jonasray-wf avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.