53
REACT 101 Anatoliy Sieryi Submit PHP 2016

React 101 by Anatoliy Sieryi

Embed Size (px)

Citation preview

REACT 101Anatoliy SieryiSubmit PHP 2016

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();

}

Component Lifecycle

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);

THANKS!

Any questions?