## Burak Kırkıl __*Frontend Developer, VNGRS*__
HTML (Structure)
CSS (Style)
Javascript (Behaviour)
foo
├── foo.tmpl.html
├── foo.css
└── foo.js
bar
├── bar.tmpl.html
├── bar.css
└── bar.js
<div
id="jsFooController"
class="fancy-div"
data-id="458">
Lorem ipsum dolor sit amet.
</div>
MV* Frameworks
<div>You've clicked <span data-bind='text: numberOfClicks'> </span> times</div>
<button data-bind='click: registerClick, disable: hasClickedTooManyTimes'>
Click me
</button>
<div data-bind='visible: hasClickedTooManyTimes'>
That's too many clicks! Please stop before you wear out your fingers.
<button data-bind='click: resetClicks'>Reset clicks</button>
</div>
var ClickCounterViewModel = function() {
this.numberOfClicks = ko.observable(0);
this.registerClick = function() {
this.numberOfClicks(this.numberOfClicks() + 1);
};
this.resetClicks = function() {
this.numberOfClicks(0);
};
this.hasClickedTooManyTimes = ko.pureComputed(function() {
return this.numberOfClicks() >= 3;
}, this);
};
ko.applyBindings(new ClickCounterViewModel());
<!-- heroes.component.html -->
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
// heroes.component.ts
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
/* heroes.component.css */
.heroes li {
background-color: #EEE;
margin: .5em;
padding: .3em 0;
}
<ul>
{{#musketeers}}
<li>{{.}}</li>
{{/musketeers}}
</ul>
var data = {
"musketeers": ["Athos", "Aramis", "Porthos", "D'Artagnan"]
};
function loadUser() {
$.get('template.mst', function(template) {
var rendered = Mustache.render(template, data);
$('#target').html(rendered);
});
}
app(state) => view
app(state) => view_t0
sideEffect > app(updatedState) => view_t1
anotherSideEffect > app(updatedState) => view_t2
...
?
f( g() ) => view
Virtual DOM is the representation of DOM as an object. When changes to state of application are made, new Virtual DOM is compared(applying diffing algorithms) with DOM and only changes are reflected, not causing full re-rendering of DOM.
<div id="foo">Hello world</div>
someTemplateFunc("div", {id: "foo"}, "Hello world");
var h = require('hyperscript')
h('div#page',
h('div#header',
h('h1.classy', 'h', { style: {'background-color': '#22f'} })),
h('div#menu', { style: {'background-color': '#2f2'} },
h('ul',
h('li', 'one'),
h('li', 'two'),
h('li', 'three'))),
h('h2', 'content title', { style: {'background-color': '#f22'} }),
h('p',
"so it's just like a templating engine,\n",
"but easy to use inline with javascript\n"),
h('p',
"the intention is for this to be used to create\n",
"reusable, interactive html widgets. "))
https://github.com/hyperhype/hyperscript
// .jsx syntax
var profile =
<div>
<img src="avatar.png" className="profile" />
<h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>
// output
var profile =
React.createElement("div", null,
React.createElement("img",
{ src: "avatar.png", className: "profile" }
),
React.createElement("h3", null,
[user.firstName, user.lastName].join(" ")
)
)
<html>
...
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
// .jsx syntax
var profile =
<div>
<img src="avatar.png" className="profile" />
<h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>
</script>
...
</html>
React + ReactDOM = HTML
React + 📱 = ReactNative
React + WebVR = React 360
$ npm init
$ npm install react react-dom
$ npm install -D @babel/core @babel/preset-env @babel/preset-react
$ npm install -D webpack webpack-cli webpack-dev-server babel-loader
.babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
webpack.config.js
const webpack = require('webpack')
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js',
},
devServer: {
contentBase: './dist',
},
}
package.json
{
"name": "minimal-react-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --mode development"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6"
},
"devDependencies": {
"@babel/core": "^7.4.0",
"@babel/preset-env": "^7.4.2",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.5",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"
}
}
- Virtual DOM is faster than a conventional full refresh model (refreshing pages partially);
- Mild learning curve, doesn’t require learning multiple specific concepts;
- Reusable code components;
- Good SEO when used together with a server-side renderer;
- A stable working code due to one-directional data;
- Easy debugging;
- Easy HTML decomposition into independent and reusable pieces of code;
- Easy testing with JEST.
- Functional Components
- Class Components
const App = () => {
return (
<h1>Hello World</h1>
)
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
header: 'Hello World'
}
}
render() {
return (
<h1>{this.state.header}</h1>
)
}
}
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = { seconds: 0 };
}
tick() {
this.setState(state => ({
seconds: state.seconds + 1
}));
}
componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
return (
<div>
Seconds: {this.state.seconds}
</div>
);
}
}
ReactDOM.render( <Timer />,
document.getElementById('timer-example')
);
### Instance Properties
- props
- state
### Instance Methods
- setState
- forceUpdate
- constructor
- componentDidMount
- shouldComponentUpdate
- static getDerivedStateFromProps()
- getSnapshotBeforeUpdate()
- componentDidUpdate
- componentWillUnmount
- static getDerivedStateFromError(error)
- render
- defaultProps
- displayName
// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});
For example, this code may fail to update the counter:
// Wrong
this.setState({
counter: this.state.counter + this.props.increment,
});
// Correct
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
### Teşekkürler