繁體中文 redux-saga 文件翻譯:
Clone or download
Pull request Compare This branch is 54 commits ahead, 350 commits behind redux-saga:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
build
dist
docs
effects
examples
logo
src
test
utils
.babelrc.js
.bookignore
.browserslistrc
.eslintrc.json
.gitignore
.lintstagedrc
.travis.yml
LICENSE
LICENSE-logo.md
README.md
README_ja.md
README_ru.md
README_zh-cn.md
README_zh-hant.md
SUMMARY.md
book.json
effects.d.ts
index.d.ts
package.json
rollup.config.js
utils.d.ts

README.md

Redux Logo Landscape

redux-saga

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

redux-saga 是一個針對在 React/Redux 應用程式中,可以更容易建立 side effect 的 library(例如:非同步的事件像是資料的 fetch 和存取瀏覽器的快取),執行效率更高,更容易測試,在處理錯誤時更容易。

想法上,redux-saga 像是一個獨立的 thread 在你的應用程式,專門負責 side effect。redux-saga 是 redux 的 middleware,意思說從主要應用程式標準的 redux action 可以啟動、暫停和取消 thread,它可以存取整個 redux 應用程式的 state 和 dispatch redux 的 action。

使用 ES6 的 Generators 功能讓非同步的流程可以更容易閱讀、撰寫和測試,如果你還不熟悉的話,這裡有一些介紹的連結。透過這樣的方式,這些非同步的流程看起來就像標準 JavaScript 同步程式碼(像是 async/await,但是 generators 還有一些更棒而且我們需要的功能)。

你可能已經使用 redux-thunk 來處理你資料的 fetch。不同於 redux thunk,你不會再出現 callback hell 了,你可以簡單測試非同步的流程並保持你的 action 是 pure 的。

入門

安裝

$ npm install --save redux-saga

or

$ yarn add redux-saga

或者,你可以直接在 HTML 頁面 <script> 標籤使用提供的 UMD build,請參考這個章節

使用範例

假設我們有一個 UI,當按下按鈕時,從遠端伺服器取得一些使用者的資料(為了簡單表示,我們只是顯示觸發 action 的程式)。

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

Component dispatch 一個原生 action 物件到 Store。我們將建立一個 Saga 來觀察所有 USER_FETCH_REQUESTED action 並觸發呼叫一個 API 取得使用者資料。

sagas.js

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

// 工作的 Saga:當 action 是 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});
   }
}

/*
  在每次 dispatch `USER_FETCH_REQUESTED` action 時,啟動 fetchUser。
  允許同時取得使用者。
*/
function* mySaga() {
  yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}

/*
  另外你也可以使用 takeLatest。

  但不允許同時取得使用者。當一個 fetch 已經在 pending 時,如果取得 dispatch「USER_FETCH_REQUESTED」,
  正在等待的 fetch 會被取消,只執行最新的發出的 USER_FETCH_REQUESTED。
*/
function* mySaga() {
  yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

為了要執行 Saga,我們將使用 redux-saga middleware 來連結 Redux Store。

main.js

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

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

// 建立 saga middleware
const sagaMiddleware = createSagaMiddleware()
// 將 saga middleware mount 在 Store 上
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

// 然後執行 saga
sagaMiddleware.run(mySaga)

// render 應用程式

文件

Translation

在瀏覽器使用 umd build 版本

dist/ 資料夾也有一個 redux-sagaumd build 可以使用。當使用 umd build 的 redux-sagaReduxSaga 作為在 window 的全域變數。這能讓你在建立 Saga middleware 不需要使用 ES6 的 import 語法:

umd 版本在你不使用 Webpack 或 Browserify 相當的有用。你可以從 unpkg 直接存取。

以下的 build 都是可用的:

**重要!**如果你的目標瀏覽器不支援 ES2015 generators,你必須 transpile 它們(babel plugin)和提供一個有效的 runtime,像是這個。 Runtime 必須被引入在 redux-saga 之前:

import 'regenerator-runtime/runtime'
// 接著
import sagaMiddleware from 'redux-saga'

從原始碼中來建立範例

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

以下的範例都是從 Redux repos 所移植(到目前為止)過來的:

Counter 範例

這裡有三個 counter 的範例。

counter-vanilla

這個範例使用原生的 JavaScript 和 UMD build。所有的原始碼都在 index.html 內。

如果要啟動範例,只要在你的瀏覽器打開 index.html

重要:你的瀏覽器必須支援 Generators。最新版本的 Chrome 和 Firefox、Edge 已經支援。

counter

這個範例使用 webpack 和高階的 takeEvery API。

$ npm run counter

# generators 的測試 sample
$ npm run test-counter

cancellable-counter

這個範例使用底層的 API 來證明 task 被取消。

$ npm run cancellable-counter

Shopping Cart 範例

$ npm run shop

# generators 的測試 sample
$ npm run test-shop

async 範例

$ npm run async

# generators 的測試 sample
$ npm run test-async

real-world 範例(使用 webpack 和 hot reloading)

$ npm run real-world

# 抱歉,還沒有測試。

TypeScript

Redux-Saga 與 TypeScript 需要 DOM.IterableES2015.Iterable。如果你的 targetES6,你或許已經設定好了,然而對於 ES5,你將需要自己把它們加入。 確認你的 tsconfig.json 檔案,和官方的 compiler 選項 文件。

Logo

你可以在 logo 目錄 找到不同風格的 Redux-Saga 官方 logo。

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]