Upload
binary-studio
View
39
Download
0
Embed Size (px)
Citation preview
Anatoliy Sieryi
JS DeveloperBinary Studio Academy
JS group coach
“Sir are you classified as human?”“Negative, I am a meat popsicle”
ReactA JAVASCRIPT LIBRARY FOR BUILDING USER
INTERFACESDeclarativeReact makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.
Declarative views make your code more predictable and easier to debug.
Component-BasedBuild encapsulated components that manage their own state, then compose them to make complex UIs.
Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.
Learn Once, Write AnywhereWe don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code.
React can also render on the server using Node and power mobile apps using React Native.
React
◉ Vanilla JS◉ Vanilla JS◉ Vanilla JS◉ Vanilla JS. Kinda◉ Vanilla JS
documentation
Angular 2
◉ Typescript◉ Batteries Included◉ DSL◉ HTML Templates◉ Typescript
documentation
Hello World Component
// React.createElement(component, [props], [...children])
function Hello(props) {
return React.createElement('div', null, `Hello, ${props.name}`);
}
React.createElement(Hello, { name: "World" });
Enter The JSX
function Hello(props) {
return <div>{`Hello, ${props.name}`}</div>;
}
<Hello name="World" />
// <div>Hello, World</div>
JSX example
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
<i className="fa fa-first-order" />
<MyComponent />
</div>
);
Object - Oriented Style
class Hello extends React.Component {
render() {
return <div>{`Hello, ${this.props.name}`}</div>;
}
}
Without ES2015
var Hello = React.createClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
Hello World App / index.html
<html>
<head>
<title>React is Awesome</title>
</head>
<body>
<div id="root"></div>
<script src="app.js"></script>
</body>
</html>
Hello World App / app.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './components/Hello';
ReactDOM.render(
<Hello name="World" />,
document.getElementById('root')
);
import React from 'react';
import ListItem from './ListItem';
export class List extends React.Component {
render() {
return (
<div className="list">
{
this.props.list.map(item =>
<ListItem key={list.id} data="list" />)
}
</div>
);
}
}
import React from 'react';
const warningStyle = {
color: '#ff0000',
fontSize: 'large',
'font-weight': 'bold'
}
export class Warning extends React.Component {
render() {
return (
<div style={warningStyle}>NOOOOOOOO!</div>
);
}
}
export class SomePage extends React.Component {
render() {
return (
{
this.props.isLoggedIn ?
<Welcome />
:
<Forbidden />
}
);
}
}
export class MyButton extends React.Component {
handleClick(e) {
alert(e.target.value);
}
render() {
return (
<input
className="my-button"
type="button"
value="Click me!"
onClick={this.handleClick}
/>
);
}
}
Synthetic Events
boolean bubblesboolean cancelableDOMEventTarget currentTargetboolean defaultPreventednumber eventPhaseboolean isTrustedDOMEvent nativeEvent
void preventDefault()boolean isDefaultPrevented()void stopPropagation()boolean isPropagationStopped()DOMEventTarget targetnumber timeStampstring type
State
constructor(props) {
super(props);
this.state = {
activeTab: this.props.tabs[0].id,
foo: 'bar'
};
}
onSwitch(id) {
this.setState({ activeTab: id });
}
render() {
const tab = this.props.tabs.find(tab =>
tab.id === this.state.activeTab);
return (
<div className="tabs">
<TabControls
tabs={this.props.tabs}
onSwitch={this.onSwitch.bind(this)}
/>
<TabContent data={tab} />
</div>
);
}
Refs
<input
type="text"
ref={inputNode => this.textInput = inputNode}
/>
scrollToInput() {
this.textInput.scrollIntoView();
}
<input
type="text"
ref="textInput"
/>
focusOnInput() {
this.refs.textInput.focus();
}
componentDidMount() {
fetch('data.json').then(res => {
this.setState({
data: res.data
});
});
};
componentWillMount() {
this.interval = setInterval(() => {
console.log('tick')
}, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
React-Router
import { Router, Route, browserHistory } from 'react-router';
// browserHistory / hashHistory / createMemoryHistory
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="users" component={Users}>
<Route path="/user/:userId" component={User}/>
</Route>
<Route path="*" component={NoMatch}/>
</Route>
</Router>
), document.getElementById('root'));
Basic Configuration
import { createStore, combineReducers } from 'redux';
import { Provider } from 'react-redux';
const rootReducer = combineReducers({ myReducer, myReducer2 });
const store = createStore(rootReducer);
ReactDOM.render(
<Provider store={store}>
<MyRootComponent />
</Provider>,
document.getElementById('root')
);
Actions
export const DO_A_BARREL_ROLL = 'DO_A_BARREL_ROLL';
export const CHANGE_USER_NAME = 'CHANGE_USER_NAME';
export function doABarrelRoll() {
return {
type: DO_A_BARREL_ROLL
};
}
export function changeUserName(newName) {
return {
type: CHANGE_USER_NAME,
payload: {
newName
}
};
}
Async Actions (redux-thunk)
export function getCustomers(params) {
return (dispatch, getStore) => {
const store = getStore();
api.getCustomers(params).then(res => {
dispatch(populateCustomers(res.data));
});
};
}
export function populateCustomers(customers) {
return {
type: POPULATE_CUSTOMERS,
payload: {
customers
}
};
}
Reducer
import { DO_A_BARREL_ROLL } from './MyPageActions';
const initialState = {
barrelRollsDone: 0
};
export default function myPage(state = initialState, action) {
switch (action.type) {
case DO_A_BARREL_ROLL:
return Object.assign({}, state, {
barrelRollsDone: state.barrelRollsDone + 1
});
default:
return state;
}
}
Container (Smart Component)
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
function mapStateToProps(state) {
return {
myPage: state.myPage
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(Object.assign({}, myPageActions), dispatch)
};
}
export MyComponent;
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
Links
ReactReduxThe Evolution of Flux FrameworksWebpackReact boilerplatesHow it feels to learn JavaScript in 2016