@jeremy_dardour @loiccarbonne Credits: Sitepoint
Modern Javascript Base
Angular
React Dev Tool
Augury
// 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';
}
Clear error messages
<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
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)
Context API
State managers
Data services (singletons)
State managers
<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>
Sometimes displaying similar APIs...
...sometimes very different ones
Compares JS objects
Only renders changed elements
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
Reactive programing
Real Time
"You can think of an observable as an array whose items arrive asynchronously over time." Angular docs
20+ classes
120+ operators
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
Easier testing
More flexible code
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();
}));
...
Complex API
Manual update of lifecycle methods
Unclear error messages
+ 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
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
... 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
Angular is a Framework
React is a library
Typed / Object Oriented
is more structured but not as fun as
Working with helped us to think in components and with state management
Working with helped us to structure our projects and write better HTML
@jeremy_dardour
@loiccarbonne