React + Flux (Alt)

Post on 12-Apr-2017

7.033 views 1 download

Transcript of React + Flux (Alt)

React? Já ouvi falar

Temas abordados

1. Problemas atuais da web

2. Onde a web está

3. Futuro?

4. Como o desenvolvimento é hoje

5. React

6. Flux

Cezar Luiz

Programador Front-End

JavaScript <3

Trabalha na Snowman Labs

23 anos

Web nos diasde hoje

Muita demandade informação

Muita gente conectada

performance !important

Tempo derespostadeve ser cadavez menor

Onde a web

está presente

Falando sobrefront-end

Muito do que se faz hoje

MVC

Mineração de DOM - getElementById, etc

Adiciona classe, retira classe

Problemas de compatibilidade

Dificuldade em escalar e aceitar

grande quantidade de dados

Problemas com MVC

“MVC got reallycomplicatedreally quickly”

!

Virtual DOM

React abstracts away the DOM from

you, giving a simpler programming

model and better performance. React

can also render on the server using

Node, and it can power native apps

using React Native.

Data Flow

React implements one-way reactive data flow which reduces boilerplate and is easier to reason about than

traditional data binding.

!framework

Por que não

pensar mais na

sua aplicação, na lógica,

do que ficar se preocupando

com o “DOM”?

import React from 'react';import ReactDOM from 'react-dom';

class HelloWorld extends React.Component {

render() { return <div>Hello World!</div> }

}

ReactDOM.render(<HelloWorld />, mountNode);

JSX

import React from 'react';import ReactDOM from 'react-dom';

class HelloWorld extends React.Component {

render() { return React.createElement( "div", null, "Hello World" ); } }

ReactDOM.render(React.createElement(HelloWorld), mountNode);

JS compilado

state e PROPS

Onde gerenciamos os dados

da nossa aplicação

import MailHeader from './MailHeaderComponent';

import MailButtons from './MailButtonsComponent';

import MailsTable from './MailTablesComponent';

class Mails extends React.Component {

render() {

return (

<div className="mails-container">

<MailHeader />

<MailButtons />

<MailsTable />

</div>

);

}

}

import HeaderTitle from './header/HeaderTitleComponent';

import HeaderSearch from './header/HeaderSearchComponent';

import Profile from './ProfileComponent';

class MailHeader extends React.Component {

render() {

return (

<header className="mail-header">

<HeaderTitle title="Inbox" />

<HeaderSearch placeholder="Search..." />

<Profile user={user} />

</header>

);

}

}

import MailRow from './MailRowComponent';

class MailTable extends React.Component {

constructor(props) { super(props);

this.state = { loading: false, mails: [] }; }

componentDidMount() { this.setState({ loading: true });

$.ajax({ url: `${host}/mails` }) .done((response) => { this.setState({ mails: response.results }); }) .complete(() => { this.setState({ loading: false }); }); }

render() { if (this.state.loading) { return <p>Carregando emails...</p> }

if (!this.state.mails.length) { return <p>Nenhum email por enquanto.</p> }

return ( <table className="mails-table"> <thead>...</thead>

<tbody> {this.state.mails.map((mail) => { return <MailRow mail={mail} /> })} </tbody> </table> ); }

}

import MailRow from './MailRowComponent';import $ from 'jquery';

class MailTable extends React.Component {

constructor(props) { super(props);

this.state = { loading: false, mails: [] }; }

...

}

import MailRow from './MailRowComponent';import $ from 'jquery';

class MailTable extends React.Component {

...

componentDidMount() { this.setState({ loading: true });

$.ajax({ url: `${host}/mails` }) .done((response) => { this.setState({ mails: response.results }); }) .complete(() => { this.setState({ loading: false }); }); }

...

}

import MailRow from './MailRowComponent';

class MailTable extends React.Component {

...

render() { if (this.state.loading) { return <p>Carregando emails...</p> }

if (!this.state.mails.length) { return <p>Nenhum email por enquanto.</p> }

return ( <table className="mails-table"> <thead>...</thead>

<tbody> {this.state.mails.map((mail) => { return <MailRow mail={mail} /> })} </tbody> </table> ); }

}

class MailRow extends React.Component {

changeCheck() {

let checkbox = this.refs.checkbox;

let dom = React.findDOMNode(checkbox); // Não é tão necessário

let { value, name, type } = checkbox;

...

}

render() {

return (

<tr>

<td>

<input

onChange={this.changeCheck.bind(this)}

type="checkbox"

name="checkMail"

ref="checkbox"

/>

</td>

<td>{this.props.name}</td>

<td>{this.props.resume}</td>

<td>{this.props.date}</td>

</tr>

);

}

}

c o m p o n e n t i z a ç ã o

ciclode vida

3 partes principais

Mounting - Um componente irá ser inserido no DOM.

Updating - Um componente está a ser re-renderizado

para determinar se o DOM deverá ser atualizado. (Virtual DOM)

Unmounting - Um componente está sendo removido do DOM.

Além disso, o React fornece métodos de ciclos de vida para

você interceptar esse processo. Métodos do tipo “will”.

Mounting - 3 métodos

getInitialState - Chamado antes de um componente ser

montado. Componentes que usam state devem implementar

isso para retornar dados iniciais.

componentWillMount - Chamado imediatamente antes

de ocorrer a montagem.

componentDidMount - Chamado imediatamente depois

de ocorrer a montagem. Se precisar alterar o DOM, deve vir aqui.

Updating - 4 métodoscomponentWillReceiveProps(object nextProps) - Chamadoquando um componente recebe novas propriedades.

shouldComponentUpdate(object nextProps, object nextState)Deve retornar um boolean se o componente deverá seratualizado ou não.

componentWillUpdate(object nextProps, object nextState)Chamado imediatamente antes de uma atualização acontecer.Não pode chamar this.setState aqui.

componentDidUpdate(object prevProps, object prevState)Chamado imediatamente depois da atualização acontecer.

Unmounting - 1 método

componentWillUnmount - Chamado imediatamente antesde um componente ser desmontado e destruído. Limpezasdevem ser feitas aqui.

state props refs renderciclos de vida

componentizaçãoJSX e JS compilado

UI complexas event system (onClick onChange...)

ajaxisso é React

E o tal do flux?

!framework

Arquiteturade aplicaçãopara construirinterfaces

“simplificar”

exemploscom altjs

// dispatcher.js

import alt from 'alt';

let alt = new Alt();

export default alt;

// actions/MailActions.js

import alt from '../dispatcher';import $ from 'jquery';

class MailActions {

getMails() { $.ajax({ url: `${host}/mails` }) .done((res) => { this.actions.getMailsSuccess(res); }) .fail(() => { this.actions.getMailsFail(); });

return true; }

getMailsSuccess(res) { return res; }

getMailsFail() { // Envia uma notificação de erro para o usuário na tela

return false; }

}

export default alt.createActions(MailActions);

// stores/MailStore.js

import alt from '../dispatcher';import MailActions from '../actions/MailActions';

class MailStore {

constructor() { this.state = { loading: false, error: false, mails: [] };

this.bindActions(MailActions); }

onGetMails() { this.setState({ loading: true, error: false }); }

onGetMailsSuccess(response) { this.setState({ loading: false, mails: response.result }); }

onGetMailsFail(err) { this.setState({ loading: false, error: err, mails: [] }); }

}

export default alt.createStore(MailStore, 'MailStore');

// components/MailTableComponent.jsimport MailRow from './MailRowComponent';import MailActions from '../actions/MailActions';import MailStore from '../stores/MailStore';

class MailTable extends React.Component {

constructor(props) { super(props);

this.state = MailStore.getState(); this.onMailChange = this.onMailChange.bind(this); }

componentDidMount() { MailStore.listen(this.onMailChange);

MailActions.getMails(); }

componentWillUnmount() { MailStore.unlisten(this.onMailChange); }

onMailChange(state) { this.setState(state); }

render() { if (this.state.loading) { return <p>Carregando emails...</p> }

if (!this.state.mails.length) { return <p>Nenhum email por enquanto.</p> }

return ( <table className="mails-table"> <thead>...</thead>

<tbody> {this.state.mails.map((mail) => { return <MailRow mail={mail} /> })} </tbody> </table> ); }

}

// components/MailTableComponent.jsimport MailRow from './MailRowComponent';import MailActions from '../actions/MailActions';import MailStore from '../stores/MailStore';

class MailTable extends React.Component {

constructor(props) { super(props);

this.state = MailStore.getState(); this.onMailChange = this.onMailChange.bind(this); }

...

}

// components/MailTableComponent.jsimport MailRow from './MailRowComponent';import MailActions from '../actions/MailActions';import MailStore from '../stores/MailStore';

class MailTable extends React.Component {

...

componentDidMount() { MailStore.listen(this.onMailChange);

MailActions.getMails(); }

componentWillUnmount() { MailStore.unlisten(this.onMailChange); }

onMailChange(state) { this.setState(state); }

...

}

// components/MailTableComponent.jsimport MailRow from './MailRowComponent';import MailActions from '../actions/MailActions';import MailStore from '../stores/MailStore';

class MailTable extends React.Component {

...

render() { if (this.state.loading) { return <p>Carregando emails...</p> }

if (!this.state.mails.length) { return <p>Nenhum email por enquanto.</p> }

return ( <table className="mails-table"> <thead>...</thead>

<tbody> {this.state.mails.map((mail) => { return <MailRow mail={mail} /> })} </tbody> </table> ); }

}

“simplificar”

O que ele pode fazer por nós

alta escalabilidade

fácil manutenção

isomorfismo

native apps com react-native

programação reativa

Quem já usa

airbnb netflix yahoo asanaatlassian coursera bbc deezerdropbox facebook instagram

imdb imgur marvelappperiscope reddit salesforceuber whatsapp globoplay

(brinks)

Obrigado!

{ github: “CezarLuiz0”, twitter: “cezar_luiz”, email: “cezarluiz.c@gmail.com”}