@jeremy_dardour       @loiccarbonne                                                                                                     Credits: Sitepoint

Two            Fans sent to                  Battleground

React

Angular

Feelings

Tips

How to choose

Let's get started!

Two different basic stacks

Modern Javascript Base

Angular

Two different learning curves

  • Small basis to learn
  • Lots of others library
  • Lots of design patterns
  • Observables (RxJS)
  • Then you are all set

Launch your project

Prepare your coding gear

React Dev Tool

Augury

Prepare your coding gear

Documentation

Let's Code!

Writing components

// Hello.jsx

export class Hello extends Component {
  render() {
    return (
      <div>
        Hello { this.props.name }!
      </div>
    );
  }
}

Hello.propTypes = {
  name: React.PropsTypes.string
}

Hello.defaultProps = {
  name: 'FullStackLondon'
};
//app.module.ts

@NgModule({
  declarations: [
    HelloComponent,
  ],
})
export class AppModule {}
//hello.component.html

<div>
    Hello {{ name }}!
</div>
//hello.component.ts

@Component({
  selector: 'hello-component',
  templateUrl: './hello.component.html',
  styleUrls: ['./hello.component.less'],
})
export class HelloComponent {
  @Input() name = 'FullStackLondon';
}

Writing components - JSX

Clear error messages

JSX - Accessibility

<div style="list">
  <div style="list-elem">1</div>
  <div style="list-elem">2</div>
</div>



<ul style="list">
  <li style="list-elem">1</li>
  <li style="list-elem">2</li>
</ul>



<div onClick="function">Button</div>


<button onClick="function">Button</button>

Accessibility

Usual user behaviours

Communication between components

Props

Callback

@Input

@Output and EventEmitter

// declare fields
@Input() data: string;
@Output() handleEvent = new EventEmitter();
// use it
handleEvent.emit(value)
<MyChildComponent 
    [data]="data" 
    (handleEvent)="myFunction($event)">
<MyChildComponent 
    data={data} 
    handleEvent={myFunction}>
// declare in PropTypes
data: PropTypes.string,
handleEvent: PropTypes.func,
// use it
this.props.handleEvent(value)

App Data Management

Context API

State managers

Data services (singletons)

State managers

The first obstacles!

<TodoList title={'Todo list'}>
  {this.props.listItems.map((listItem) =>
    (<ListItem item={listItem} />)
  )}
</TodoList>
<todo-list [title]="Todo list">
  <todo-list-item 
    *ngFor="let listItem of listItems" 
    [item]="listItem" />
</todo-list>
<todo-list>
  <h1>Todo list</h1>
  <ul class="group">
    <todo-list-item>
      <li class="item">learn react</li>
    </todo-list-item>
    <todo-list-item>
      <li class="item">learn angular</li>
    </todo-list-item>
    <todo-list-item>
      <li class="item">decide</li>
    </todo-list-item>
  </ul>
</todo-list>

Harder to style and understand HTML

<h1>Todo list</h1>
<ul class="group">
  <li class="item">learn react</li>
  <li class="item">learn angular</li>
  <li class="item">decide</li>
</ul>

Component wrappers

Component Lifecycle

  • constructor
  • ngOnChanges
  • ngOnInit
  • ngOnDestroy
  • 5 more methods
  • constructor
  • getDerivedStateFromProps
  • componentDidMount
  • componentWillUnmount
  • render
  • 4 other methods

Sometimes displaying similar APIs...

...sometimes very different ones

Component Lifecycle - Virtual DOM

Compares JS objects

Only renders changed elements

Component lifecycle

import { Component } from '@angular/core';

@Component({
  selector: 'app-header',
  templateUrl: `
    <div class="header-container">
      {{ countMyRenders() }}
    </div>
  `,
})
export class HeaderComponent {
  countMyRenders() {
    console.count('render of header component');
  }
}

Do not calculate methods in template in Angular

Observables are powerful...

Reactive programing

 

Real Time

"You can think of an observable as an array whose items arrive asynchronously over time." Angular docs

...but complicated to master...

 20+ classes

120+ operators

...and you don't have a choice

DOM

LISTENERS

@Injectable()
export class ApiService {
  method() {...}
}

...

@NgModule({
  declarations: [],
  imports: [],
  providers: [
    ApiService,
  ],
})
export class AppModule {}

...

@Component({
  selector: 'app-header',
})
export class HeaderComponent {
  constructor (apiService: ApiService) {
    this.apiService.method();
  }
}

Lot of boiler-plate

Dependency injection

Easier testing

More flexible code

Tests - Angular

describe('MyComponent', () => {
  let fixture;
  let component;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        FormsModule,
        HttpClientModule,
      ],
      declarations: [
        MyComponent,
      ],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.debugElement.componentInstance;
    fixture.detectChanges();
  }));
  ...

Boiler Plate

Mock with DI

  ...

  it('should be a great test', fakeAsync(() => {
    // mandatory to refresh dom
    fixture.detectChanges();
    // mandatory to wait for asynchrone events to finish
    tick()
    fixture.detectChanges();
    
    ...
    fixture.detectChanges();
    tick()
    fixture.detectChanges();
  }));
  ...

Tests - Angular

Complex API

Manual update of lifecycle methods

Tests - Angular

Unclear error messages

Tests - React

+ Enzyme

Snapshot testing

Easy to set up

Hard to mock business functions

describe('Super test case', () => {
  beforeEach(() => {
    wrapper = shallow(<MyComponent {...props} />);
  });

  it('should be a great test', () => {
    // Set state
    wrapper.setState({ name: 'bar' })
    // Call component Class methods
    wrapper.instance().handleClick();
    // check children components props
    expect(image.prop('src')).toBe('url');
    // Simulate events
    wrapper.find(MyOtherComponent).simulate('click');
  });
});

Simple API

Architecture

Angular Modularity

Architecture - Angular

Core module

Heroes module

Shared module

App module

On one side the doc offers a solution for everything...

source: https://angular.io/guide/styleguide#overall-structural-guidelines

A complete style guide

One proposed organisation

One way of naming files

Architecture - React

... on the other side everything is up to you

.js vs .jsx

File naming

Business logic files

Organizing by Page

Styling

Typing

Function vs Class

shared components

Difference of philosophy

Angular is a Framework

React is a library

...Both can make to a good recipe...

...or end up in spaghetti-code

How to choose ?

How to choose - Team Background

Typed / Object Oriented

How to choose - Team Background

How to choose - Team Size

How to choose - Project

How to choose - Targeting Mobile

How to choose - Real Time

How to choose - Personal Preference

How to choose - Personal Preference

We promised you

Our Feeling

  is more structured but not as fun as

Our Tips

Working with         helped us to think in components and with state management

 

 

Working with          helped us to structure our projects and write better HTML

Thank you

@jeremy_dardour

@loiccarbonne

React vs Angular Fullstack

By Loïc Carbonne

React vs Angular Fullstack

  • 387