Skip to content

Instantly share code, notes, and snippets.

@ricardocanelas
Last active June 10, 2019 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricardocanelas/de9e7c7d40a046d710f0d629df000f45 to your computer and use it in GitHub Desktop.
Save ricardocanelas/de9e7c7d40a046d710f0d629df000f45 to your computer and use it in GitHub Desktop.
React Notes

FUNDAMENTOS DE REACT

Aula 1 - Introdução

Aula 2 - Renderização da UI com o React

Aula 3 - Gerenciamento de Estados

Aula 4 - Gerenciamento de Estados

Aula 5 - Gerenciando a localização na aplicação com o React Router

Aula 1 - Introdução

Composição

A composição ocorre quando funções simples são combinadas para criar outras mais complexas. Pense em cada função como um bloco de construção único que faz uma coisa (DOT - "does one thing")

Código imperativo

Imperative significa: expressar um comando; comandar.

Quando um código de JavaScript é escrito de maneira imperativa, dizemos ao JavaScript exatamente o que fazer e como fazer isso.

Código declarativo

Com o código declarativo, não codificamos todas as etapas para chegar ao resultado final. Em vez disso, declaramos o que queremos fazer, e o JavaScript se encarregará de fazê-lo.

const people = ['Amanda', 'Geoff', 'Michael', 'Richard', 'Ryan', 'Tyler']
const excitedPeople = people.map(name => name + '!')

"JavaScript", vou dar esse conjunto de nomes e quero que você mapeie-os e coloque uma exclamação em cada um ao final. Depois, devolva-me o resultado, por favor."

O código imperativo instrui o JavaScript sobre como ele deve executar cada etapa. Com o código declarativo, dizemos ao JavaScript o que queremos obter e o deixamos tomar conta das etapas de execução.

O React é declarativo, pois escrevemos o código que queremos, e o React é responsável por pegar o código declarado e executar todas as etapas de JavaScript/DOM para nos fornecer o resultado desejado.

Data-Binding

Unidirecional (one-way data bindings)

Os dados fluem em uma única direção, do pai para o filho. React usa esse tipo de direcionamento.

Bidirecional (two-way data bindings)

Frameworks de front-end, como o Angular e o Ember, utilizam a ligação de dados bidirecionais (two-way data bindings).

Map & Filter

const people = ['Rico', 'Canelas', 'Fernanda'];
const lenPeople = people.map(person => person.length);
const shortsPeople = people.filter(person => person.length < 5);

Aula 2 - Renderização da UI com o React

CreateElement

O método .createElement() do React requer uma descrição de um elemento e retorna um objeto JavaScript simples.

O .createElement() retorna um elemento Root

import React from 'react'

const helloElem = React.createElement('div', {'className': 'world'}, 'Hello World!')

const myListElem = React.createElement('ol', null, 
  React.createElement('li', null, 'Michael'),
  React.createElement('li', null, 'Richard'),
  React.createElement('li', null, 'Evelly'),
)

const people = ['Michael', 'Richard', 'Evelly']
const peopleListElem = React.createElement('ol', null, 
  people.map((person, index) => (
    React.createElement('li', { key: index }, person),
  ))
)

Usando o 'react-dom' para renderizar.

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

const helloElem = React.createElement('div', {'className': 'world'}, 'Hello World!');
ReactDOM.render(helloElem, document.getElementById('root'));

JSX

Ao escrever JSX, tenha em mente que ele deve retornar apenas um único elemento.

const people = ['Michael', 'Richard', 'Evelly']
const peopleListElem = (
 <ol>
  {people.map((person,index) => (
   <li key={index}>{person}</li>
  ))}
 </ol>
)

Componentes

Existe apenas um método absolutamente necessário em qualquer classe de componente de React: o método render().

Essas classes de componentes devem seguir o princípio da responsabilidade única e apenas "fazer uma coisa". Se ele gerencia muitas tarefas diferentes, pode ser uma boa idéia decompor seu componente em subcomponentes menores.

Uma ótima mentalidade para se adquirir ao criar aplicativos em React é pensar em componentes.

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

class ContactList extend React.Component {
  render () {
    $greeting = 'Hello World'
    
    return (
      <div>
        <h1>$greeting</h1>
        <p>lorem ipsum...</p>
      </div>
    )
  }
}

ReactDOM.render(
 <ContactList>,
 document.getElementById('root')
)

O JSX é incrível, mas precisa ser transpilado para JavaScript regular antes de chegar ao navegador. Normalmente, usamos um transpiler como o Babel para fazer isso. Podemos executar o Babel com uma ferramenta de build como o Webpack, que ajuda a agrupar todos nossos assets (arquivos de JavaScript, CSS, imagens, etc.) para projetos na web.

Create React App

Para simplificar essas configurações iniciais, podemos usar o pacote do aplicativo Create React, do Facebook, para cuidar de toda a configuração para nós!

npm install -g create-react-app
create-react-app contactsApp

Vai instalar: React, React-Dom, React-Scripts

React-Scripts vem com: Babel, Webpack, Webpack-Dev-Server


Aula 3 - Gerenciamento de Estados

Conceitos: Props, States, Componentes Funcionais, Componentes Controlados.

Se você deseja que seu componente armazene dados locais mutáveis, considere usar o state para manter essa informação.

Se a mudança de algumas informações ao longo do tempo não é esperada, e geralmente é projetada para ser "somente leitura" em seu aplicativo, considere usar props em vez disso.

Props

Um prop é qualquer entrada que você passa para um componente React. Assim como um atributo HTML, um nome e valor do prop são adicionados ao componente.

Podemos pensar em passar os props para componentes, assim como passamos argumentos para funções. Assim como podemos acessar os argumentos passados para uma função em JavaScript, podemos também acessar os props de um componente com this.props (ou props em componentes funcionais sem estado).

Qualquer prop passado para um componente é acessível com o objeto this.props.

Prop-Types

O PropTypes é um pacote que nos permite definir os tipos de dados que queremos ter e nos avisar, durante o desenvolvimento, se o prop que foi passado para o componente coincide ou não com o esperado.

yarn install prop-types

Componente (como class)

class User extends React.Components {
 render() {
  return (
   <p>Username: {this.props.username}</p>
  )
 }
}

Stateless Functional Components (como function)

Componente funcional sem estado.

const User = (props) => {
 return (
  <p>Username: {props.username}
 )
}

Componentes Controlados

Os componentes controlados referem-se a componentes que representam um formulário, mas a "fonte da verdade" para esse estado do formulário vive dentro do estado do componente em vez de dentro do DOM. Os benefícios dos componentes controlados são:

  • Validação de entrada instantânea
  • Desativação/habilitação de botões de maneira condicional
  • Imposição de formatos de entrada
class NameForm extends React.Component {
 state = { email: '' }
 handleChange = (event) => {
  this.setState({email: event.target.value });
 }
 render () {
  return (
   <form>
    <input type='text' value={this.state.email} onChange={this.handleChange} />
   </form>
  )
 }
}

Aula 4 - Renderizando a UI com dados externos

O render() só é usado para exibir conteúdo, apenas!

Códigos que devem lidar com requisições Ajax, requisição HTTP, recuperar dados devem estar no ciclo de vida (lifecycle events)

Lifecycle Events

componentWillMount() - invocado imediatamente antes do componente ser inserido no DOM

componentDidMount() - invocado imediatamente depois do componente ser inserido no DOM

componentWillUnmount() - invocado imediatamente antes do componente ser removido do DOM

componentWillReceiveProps() - invocado sempre que o componente está prestes a receber novas props

Em qual método do ciclo de vida você deveria realizar requisições Ajax ou de APIs? RE: componentDidMount

Cada um é executado em um momento diferente, mas podemos separá-los em três categorias:

Adicionando ao DOM

  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()

Renderizando novamente

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

Removendo do DO

  • componentWillUnmount()

LifeCycle


Aula 5 - Gerenciando a localização na aplicação com o React Router

SPA, single-page applicatiions - Aplicações de página única.

O React Router transforma projetos React em aplicações single-page

npm install --save react-router-dom

BrowserRouter

Vai ouvir as mudanças no URL, quando as mudanças acontecerem, ele faz a tela certa aparecer.

Você precisa envolver todo o seu aplicativo em um componente BrowserRouter:

import { BrowserRouter } from 'react-router-dom'

ReactDOM.render(
 <BrowserRouter><App /><BrowserRouter>,
 document.getElementById('root')
)

Link

<Link to={{
  pathname: '/courses',
  search: '?sort=name',
  hash: '#the-hash',
  state: { fromDashboard: true }
}}>
  Courses
</Link>

Route

é o componente que decidirá quais components serão renderizados com base em cada caminho de URL. Route pega um caminho que corresponde ao URL, então o Route vai renderizar uma IU.

<Route exact path='/' render={() => (
    <ListContact
        contact={this.state.contacts}
    />
)}/>

<Route path='/create' component={CreateContact} />

REACT E REDUX

Aula 1 - Por que Redux?

Aula 2 - Redux na sua essência

Aula 3 - React e Redux

Aula 4 - Arquitetando uma Redux Store

Aula 5 - Middleware para Redux

Aula 1 - Por que Redux?

Funções Puras / Pure Fuctions

As funções puras se prestam a um código de melhor qualidade, e ter isso em mente ao construir os aplicativos fará de você um programador mais capaz.

Tres items que deve ser:

  • Return one and the same result if the same arguments are passed in
  • Depend solely on the arguments passed into them
  • Do not produce side effects
const square = (x) => x * x

Veja mais em: https://www.gitbook.com/book/drboolean/mostly-adequate-guide-old/details

Funções inpuras

// Inpura
const tipPercentage = 0.15
const calculateTip = (cost) => cost * tipPercentage

// Pura
const calculateTip = (cost, tipPercentage = 0.15) => cost * tipPercentage

Programação Funcional / Functional Programming

Enfatiza funções puras..

Programação Imperativa

Enfatiza funções impuras..

Função High-order

Pega uma função (ou seja, um callback) como argumento.

Exemplo de funções HO: reduce, map, filter

Reduce()

A ideia central de .reduce() é que ela pega uma grande quantidade de dados, mas retorna um único valor.

const iceCreamStats = [
   { name: 'Amanda', gallonsEaten: 3.8},
   { name: 'Richard', gallonsEaten: 5.2}
]

iceCreamStats.reduce((accumulator, currentValue) => {
   return accumulator + currentValue.gallonsEaten
}, 0) 

// return: 9

Aula 2 - Redux na sua essência

Major players in Redux / Os principais elementos do Redux

  • Action
  • Reducers
  • The Store
  1. Action são enviadas pela store
  2. Para criar a store, precisamos do reducer.
  3. O reducer usa as actions.

Um fluxo de dados unidirecional

fluxo

Resumo: os principais conceitos do Redux são as actions, os reducers e a store. A store é o single source of truth sobre o estado de seu aplicativo, os reducers atualizam e especificam o formato da store, e as actions são pacotes de informação que dizem aos reducers que tipos de eventos aconteceram no aplicativo.

Actions

Actions são objetos JavaScript que descrevem qualquer evento que deva atualizar o estado do aplicativo.

Esses objetos devem ter uma propriedade type para distinguir o tipo específico de action que ocorreu.

Recomendações: Faça com que seus recursos enviem apenas os dados necessários! É importante manter actions o mais concentradas possíveis, sem efeitos colaterais.

{ 
    type: 'DELETE_COMMENT',
    id: 3
}

Action Creators

deleteComment = id => ({
    type: 'DELETE_COMMENT',
    id: id
})
const CREATE_MEAL = 'CREATE_MEAL'

const mealCreator = (id) => ({
    type: CREATE_MEAL,
    id
})

console.log(mealCreator(1))
// { type: 'CREATE_MEAL', id: 1 }

Reducers

Um reducer é, simplesmente, uma função à qual são passados esses dois argumentos.

Um reducer recebe o estado atual e uma action que foi despachada e, então, decide como transformar o estado atual em um estado novo, baseado na action que recebeu.

Regras:

  • Reducer deve ser uma função pura.
  • Reducer deve receber o estado atual e uma action, e retornar o novo estado
  • Reducer não deve produzir efeitos colaterais (solicitações assíncronas, alteração de variáveis de escopo, etc.)
function reducer (state = initialState, action) {
    const newState = {...state} 
    return newState // always return a state
}
function reducer (state = initialState, action) {
  switch (action.type) {
    case 'SUBMIT_USER' :
      return Object.assign({}, state, {
        user: action.user
      })
  }
}

The Store

O que comanda a parada toda

const immaStore = Redux.createStore(<reducer>)

immaStore.getState()

immaStore.dispatch(<action object>)

immaStore.subscrive(<listener function>)

All Together

https://www.youtube.com/watch?v=AlFCMlK5cpU

https://github.com/udacity/reactnd-udacimeals-complete/commit/d0d4b8ade3dea46b7a3250ea196e0f862a399672

Aula 3 - React e Redux

A maior vantagem do react-redux é percebida no despacho de actions e no acesso à store do Redux a partir dos seus componentes React

  • Provider
  • Connect

Provider

import { Provider } from 'react-redux';

const store = createStore(myReducer)

<Provider store={store}>
  <App />
</Provider>

O Provider permite que o Redux passe dados da store para quaisquer componentes React que precisem. Ele usa a funcionalidade de contexto do React para fazer isso funcionar.

Currying / Curried Function

Também pode ser chamado de 'partial application'

function greet(name, message) {
    return `${message}, ${name}!`;
}

Digamos que, por qualquer motivo, gostaríamos de esperar para message mais tarde. Uma forma de conseguir fazer isso seria retornar uma função que aceita uma mensagem, que pudesse ser chamada mais tarde.

// the curried function
const greet = (name) {
    return (message) => {
        return `${message}, ${name}!`;
    }
}

greet('Ricardo')('Yo yo')

Currying é o processo de fornecer entradas parcialmente a uma função que precisa de informações adicionais. A parte da API do Redux que usa currying é seu método connect(). Vamos dar uma olhada!..

Connect

connect() é uma função que permite que um componente obtenha dados e despache actions a partir de uma store do Redux. Sua assinatura é interessante. Usando todos os argumentos, ela fica assim:

connect(mapStateToProps, mapDispatchToProps)(MyComponent)

mapStateToProps

mapStateToProps() permite que você especifique que dados do store você quer que sejam passados para seus componente React.

Ele pega do state de store, um argumento opcional ownprops, e retorna um objeto. Veja sua assinatura completa:

mapStateToProps(state, [ownProps])
const mapStateToProps = (state, ownProps) => ({
  name: state.user.name,
  age: state.user.age
});
const mapStateToProps = (state, ownProps) => ({
  photos: state.photos.filter(photo => photo.user === ownProps.user)
});

mapDispatchToProps()

Quando você conecta um componente, aquele componente será passado automaticamente para o método dispatch() do Redux

const mapDispatchToProps = dispatch => ({
  boundUpdateName: (name) => dispatch(updateName(name))
});

Aula 4 - Arquitetando uma Redux Store

CombineReducers

combineReducers() é uma função auxiliar fornecida pelo Redux que transforma um objeto cujos valores são diferentes funções reducer em uma única função reducer.

Passamos então este “root reducer” para o createStore() para criar a store do aplicativo.

// in: reducers/root_reducer.js
import { combineReducers } from 'redux';

function users (state = {}, action) { ...}

function books (state = {}, action) { ... }

export default combineReducers({
  users,
  books,
});
// in: store/store.js

import rootReducer from '../reducers/root_reducer';

const store = createStore(rootReducer)

Normalização

Normalização é o processo de remover porções de dados duplicadas e garantir que os dados estejam estruturados da maneira menos profunda possível.

const people = {
    personA: 'myInfoA',
    personB: 'myInfoB',
    personC: 'myInfoC',
}

const friends = ['personA', 'personB']
getFriendInformation = friends.map((friend) => people[friend])

Coloque em mente: não duplique seus dados e mantenha sua store o menos profundo possível.

Aula 5 - Middleware para Redux

middleware-redux

Middleware.. um ponto de extensão criado por terceiros entre o despacho de uma action e o momento em que ela chega ao reducer.

Uma vez que o middleware recebe a action, ele pode, então, realizar uma série de operações, incluindo:

  • Produzir um efeito colateral (ex: fazer um log do estado)
  • Processar a action por si só (ex: fazendo uma requisição HTTP assíncrona)
  • Redirecionando a action (ex: para outro middleware)
  • Executar algum código durante o despacho
  • Despachar actions suplementares

...e tudo isso é feito antes da action ser encaminhada para o reducer!

Doc: https://redux.js.org/advanced/middleware

applyMiddleware()

Redux nos fornece a função applyMiddleware(), que podemos usar como nosso argumento enhancer.

store.createStore(reducer, [preloadedState], [enhancer])

applyMiddleware() aceita múltiplos argumentos, então, caso necessário, podemos aplicar mais de um middleware a um aplicativo.

const logger = store => next => action => {
  console.group(action.type)
  console.info('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  console.groupEnd(action.type)
  return result
}

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const store = createStore(
  reducer,
  composeEnhancers(
    applyMiddleware(logger)
  )
)

Middlewares:

Redux-Thunk

// store.js

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers/root_reducer';

const store = () => createStore(rootReducer, applyMiddleware(thunk));

export default store;

Nos permite escrever action creators assíncronos que retornam funções em vez de objetos, nosso novo action creator, agora, pode ser assim:

// util/todos_api_util.js

export const fetchTodos = () => fetch('/api/todos');
import * as TodoAPIUtil from '../util/todo_api_util';

export const RECEIVE_TODOS = "RECEIVE_TODOS";

export const receiveTodos = todos => ({
  type: RECEIVE_TODOS,
  todos
});

export const fetchTodos = () => dispatch => (
  TodoAPIUtil
      .fetchTodos()
      .then(todos => dispatch(receiveTodos(todos)))
);

O thunk pode, então, ser usado para atrasar o despacho de uma action ou para despachar somente se uma certa condição for satisfeita (ex: um pedido é resolvido).

Veja mais em:

Estrutura e Organização

Não existe um “jeito certo” de dividir as coisas, embora haja convenções que podemos praticar para ajudar a gerenciar a complexidade do Redux.

Exemplos de mundo real:

...fique à vontade para escolher a estrutura que fizer mais sentido para você.

Redux examples

REACT NATIVE

Aula 1 -Conhecendo o React Native e o utilizando

  • iOS usa o Xcode
  • Android usa o Android Studio
  • Expo: iOS and Android

Usando Expo

Usaremos o Create React Native App para desenvolver para iOS e para Android. Vantagens: Setup simple e rápido; sem necessidade do Xcode ou Android Studio. Desvantangens: com projetos já existentes; modulos nativos para cada sistema.

Usaremos o Expo que é um conjunto de ferramentas e serviços que nos permitem construir aplicativos nativos (iOS e Android) com Javascript. O Expo facilita a construçao de aplicativos móveis sem precisar escrever código nativo (por exemplo: Swhift, Objetive C, Java)

O Expo, junto ao Create React Native App, é a maneira mais rápida de começar.

Mas se quise Construindo Projetos com Código Nativo, clique no link.

Create-React-Native-App

npm install -g create-react-native-app ou yarn global add create-react-native-app

Expo

Instalando Android Studio

Vamos seguir o tutorial da documentação

SETUP:

  1. Install Node.js
  2. Install Pyhton2
  3. Install JSDK 8uXXX (JDK 8 is the new Java 10 and 11)
  4. Install Android Studio
  5. Install React-Native-CLI npm install -g react-native-cli

Android Studio

Quando estiver instalando, lembra-se do local de onde é instalado (Adroid SDK Installation Localtion), provavelmente em C:\Users\MyUser\AppData\Local\Android\sdk

Na primeira instalação, quando abrir o Android Studio, vai aparecer alguns alertas (na aba 'messages') para instalar pacotes ou ferramentas adicionais, faça isso. Exemplos: android-23; build tools revision 23;

Proxima coisa é criar um emulator, vá em: Tools/Android/AVD Manager. Create Virtual Device.. / Nexus5 4.95 / Marshmallow API Level 23 (porque temos o android-23 e build tools) / Finish.

Precisamos adicionar 'Environment Variables'

  • JAVA_HOME: C:\Program Files\Java\jdk1.8.0_101
  • Path: C:\Users\MyUser\AppData\Local\Android\sdk\platform-tools
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment