@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
- 451