Um modelo alternativo de side effect(efeito colateral) para Redux apps https://redux-saga.js.org/
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
docs
.gitignore
LICENSE
README.md

README.md

Redux Logo Landscape

redux-saga

Join the chat at https://gitter.im/yelouafi/redux-saga npm version CDNJS OpenCollective OpenCollective

redux-saga é uma lib que visa fazer side effects(efeitos colaterais) (i.e. coisas assincronas como data fetching e coisas impuras como acessar o cache do browser) em aplicações React/Redux mais fácil e melhor.

O modelo mental é que uma saga é como uma thread separada em sua aplicação que é unicamente responsável por side effects. redux-saga é um redux middleware, que significa que essa thread pode ser estartada, pausada e cancelada na aplicação principal com normais redux actions, ela tem acesso a todo o state(estado) da aplicação redux e pode também dispatch(dispachar) ações.

Saga usa uma feature(característica) do ES6 chamada Generators para fazer fazer fluxos assincronos fáceis de ler, escrever e testar. (Se você não está familirizada com elas Aqui tem alguns links introdutórios) Para fazê-los, fluxos assincronos veja como o padrão assincrono JavaScript code. (algo como async/await, mas generators tem coisas mais incríveis que nós precisamos)

Talvez você já tenha usado redux-thunk para lidar com sua busca de dados. Contrários ao redux thunk, você não acaba em callback hell, você pode testar fácilmente seus fluxos assincronos e suas actions continuam puras.

Iniciando

Instalar

$ npm install --save redux-saga

ou

$ yarn add redux-saga

Alternativamente, você pode usar o fornecido UMD build diretamente no <script> tag de uma página HTML. Veja Esta sessão.

Exemplo Usando

Supomos que temos uma UI para buscar alguns dados dos usuários de um servidor remoto quando um botão é clicado. ( Breve resumo, iremos mostrar apenas ações disparados no código)

class UserComponent extends React.Component {
  ...
  onSomeButtonClicked() {
    const { userId, dispatch } = this.props
    dispatch({type: 'USER_FETCH_REQUESTED', payload: {userId}})
  }
  ...
}

O Component dispara uma simples action Object na Store. Criaremos uma Saga que escuta todos os USER_FETCH_REQUESTED actions e dispara uma chamada na API para buscar usuários.

sagas.js

import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'

// trabalho do Saga: irá disparar uma ação USER_FETCH_REQUESTED
function* fetchUser(action) {
   try {
      const user = yield call(Api.fetchUser, action.payload.userId);
      yield put({type: "USER_FETCH_SUCCEEDED", user: user});
   } catch (e) {
      yield put({type: "USER_FETCH_FAILED", message: e.message});
   }
}

/*
  Estarta fetchUser em cada ação disparada `USER_FETCH_REQUESTED`.
  Permite concorrentes buscar de usuários
*/
function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

/*
  Alternativa você pode usar takeLatest.

  Não permite buscar concorrentes de usuários. Se "USER_FETCH_REQUESTED" captura dispachados enquanto uma busca já está pendente, esta busca pendente é chamada e só a mais recente irá executar.
*/
function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

Para executar nosso Saga, teremos que conectar isto ao Redux Store usando o redux-saga middleware

main.js

import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import reducer from './reducers'
import mySaga from './sagas'

// criação do saga middleware
const sagaMiddleware = createSagaMiddleware()
// agrupe na store
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

// então execute o saga
sagaMiddleware.run(mySaga)

// renderiza a aplicação

Documentação

Traduções

Usando a build umd no browser

Exibe também uma build umd do redux-saga disponível no diretório dist/. Ao usar a build do umd redux-saga está disponível como ReduxSaga no objeto window. Isso permite que você crie o middleware Saga sem usar a sintaxe ES6 import, assim:

var sagaMiddleware = ReduxSaga.default()

A versão umd é útil caso você não utilize Webpack ou Browserify. Você pode acessá-la diretamente através do unpkg.

As seguintes builds estão disponíveis:

Importante! Se o browser que você está trabalhando não suporta os ES2015 generators, você deve fornecer um polyfill válido, como o fornecido pelo babel. O polyfill deve ser importado antes do redux-saga:

import 'babel-polyfill'
// then
import sagaMiddleware from 'redux-saga'

Construindo exemplos a partir do código fonte

$ git clone https://github.com/redux-saga/redux-saga.git
$ cd redux-saga
$ npm install
$ npm test

Abaixo há os exemplos portados (até agora) dos repositórios do Redux.

exemplos de contadores

Há três exemplos de contadores.

counter-vanilla

Exemplo usando Javascript puro e build UMD. Todo o código está inline no arquivo index.html.

Para executar o exemplo, basta abrir index.html no seu browser.

Importante: seu browser deve suportar Generators. A última versão do Chrome/Firefox/Edge oferecem suporte.

counter

Exemplo usando webpack e a API de alto nível takeEvery.

$ npm run counter

# test sample for the generator
$ npm run test-counter

cancellable-counter

Exemplo usando uma API de baixo nível para demonstrar cancelamento de tarefas.

$ npm run cancellable-counter

exemplo do carrinho de compras

$ npm run shop

# test sample for the generator
$ npm run test-shop

exemplo async

$ npm run async

# test sample for the generators
$ npm run test-async

exemplo real-world (com webpack hot reloading)

$ npm run real-world

# sorry, no tests yet

TypeScript

Redux-Saga com TypeScript requer DOM.Iterable ou ES2015.Iterable. Se o seu target é ES6, provavelmente você não precisa fazer nada, mas para ES5 você precisará adicionar isso você mesmo. Verifique seu tsconfig.json e a documentação oficial para compiler options.

Logo

Você pode achar o logo oficial do Redux-Saga com diferentes versões no diretório de logos.

Apoiadores

Apoie-nos com uma doação mensal e ajude-nos a continuar nossas atividades. [Tornar-se um apoiador]

Patrocinadores

Torne-se um patrocinador e obtenha seu logotipo em nosso README no Github com um link para seu site. [Tornar-se um patrocinador]