We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
使用 redux-thunk、 redux-saga、 redux-observable、 MobX制作同样的一个小项目:
这个项目调用github API查找 github 用户,点击头像之后还可以知道这个用户的 follower 和 following。简单来说,就是调用了三次 API(即三次异步请求)。
本文不是教程,并不会手把手地教你如何使用他们,只是一个指引,一份示例,让你能够了解他们各自的特点,以便选择最适合自己的。
code
redux-thunk我们在 Redux 中操作异步最简单的方法。配合 async/await,你可以像写同步代码一样进行异步操作。
// action creators const getUsers = username => { async dispatch => { dispatch({ type: 'LOADING' }) try{ const response = await fetch(`https://example.com/`) let data = await response.json() dispatch({ type: 'SUCCESS', payload: data }) }catch(error) { dispatch({ type: 'FAILURE', error: error }) } } }
dispatch dispatch update VIEW ----------> function ----------> ACTION object ---------> REDUCER --------> STORE --------> STATE | (return async dispatch) ^ | | | | | | | dispatch | |---------------------> ACTION object -----------------------------
VIEW 会 dispatch 一个 ACTION object 或一个高阶函数(返回 async function):
redux-saga 简化了 action creator,redux-saga 通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理。Sagas 可以被看作是在后台运行的进程,监听发起的 action,然后决定基于这个 action 来做什么:是发起一个异步调用(比如一个 Ajax 请求),还是发起其他的 action 到 Store,甚至是调用其他的 Sagas。一旦出发 sagas 监听的 action,sagas 会通过一系列的effects dispatch (比如 put)一个 action。
action creator
put
// action.js export const searchUsers = (username, page) => { return { type: CONST.FETCH_GITHUB_SEARCH_USER, payload: { username, page } } }
// App/sagas.js function* fetchUsers(action) { let { username, page } = action.payload yield put({ type: CONST.FETCH_GITHUB_SEARCH_USER_LOADING }) yield call(delay, 2000) try { let response = yield call(fetch, `https://api.github.com/search/users?q=${username}&page=${page}`) let data = yield response.json() yield put({ type: CONST.FETCH_GITHUB_SEARCH_USER_SUCCESS, payload: data }) }catch(e) { yield put({ type: CONST.FETCH_GITHUB_SEARCH_USER_FAILURE, error: "No This User" }) } } export default function* () { yield takeLatest(CONST.FETCH_GITHUB_SEARCH_USER, fetchUsers) }
// sagas/index.js import AppSaga from 'containers/App/sagas' export default function* rootSaga() { yield AppSaga() }
dispatch not match update update VIEW ----------> ACTION object -----------> REDUCER --------> STORE --------> STATE | ^ | | | match | | | | (data) | | | \| dispatch | SAGAS ------------> ACTION object
VIEW dispatch 一个 ACTION object:
原理不同:Sagas 不同于 Thunks,Thunks 是在 action 被创建时调用,而 Sagas 会在应用启动时调用(但初始启动的 Sagas 可能会动态调用其他 Sagas),是常驻后台的(因为 generator)。
redux-saga 有cancel、takeLeast这些操作,这是 async 做不到的(这也是 generator 相对 async 的优势)
redux-saga 易测试,比如它可以无阻塞地调用一个 generator(fork)、中断一个 generator (cancel)。这些特性在业务逻辑复杂的场景下非常适用。测试代码详见这里
redux-saga 保持了 action 的原义,保持 action 的简洁,把所有有副作用的地方独立开来(这样action里会很干净)。这种特性让 redux-saga 在业务逻辑简单的场景下,也能保持代码清晰简洁。
你要先了解 rxjs ,然后再往下读。因为 redux-observable 就是让你能够在 Redux 中使用 rxjs。
为了方便理解 rxjs,我做了一个纯 js 版的项目 jsbin,之后能够我们再把它改成 react 版的。
dispatch not match update update VIEW ----------> ACTION object -----------> REDUCER --------> STORE --------> STATE | ^ | | | match | | | | (data) | | | \| dispatch | EPICS ------------> ACTION object
Epic 是 redux-observable 的核心,它是一个函数,接收 actions 流作为参数并且返回 actions 流: Actions 入, actions 出。返回的 actions 会通过 store.dispatch() 立刻被分发,所以 redux-observable 实际上会做 epic(action$, store).subscribe(store.dispatch)。
store.dispatch()
epic(action$, store).subscribe(store.dispatch)
可以看到,redux-observable 和 redux-saga 的数据流是相似的。关于他们的异同,可以查看这两篇文章,不再赘述:
先看一个 demo,它包含了 @action @observable @observer @computed @inject 等重要概念。
@action
@observable
@observer
@computed
@inject
modify update trigger Events -----> Actions -------------> State --------> Computed values ----------> Reactions (@action) (@observable) (@computed) (@observer) ^ | | | | (mobx-react) | |------------------------------------------------------------------------------|
MobX vs Redux: Comparing the Opposing Paradigms 演讲已经介绍,不能看视频的看 MobX vs Redux: Comparing the Opposing Paradigms - React Conf 2017 纪要 也是可以的。
向我捐助 | 关于我 | 工作机会
The text was updated successfully, but these errors were encountered:
No branches or pull requests
使用 redux-thunk、 redux-saga、 redux-observable、 MobX制作同样的一个小项目:
目录
redux-thunk
code
redux-thunk我们在 Redux 中操作异步最简单的方法。配合 async/await,你可以像写同步代码一样进行异步操作。
示例
redux-thunk flow
VIEW 会 dispatch 一个 ACTION object 或一个高阶函数(返回 async function):
redux-saga
code
redux-saga 简化了
action creator
,redux-saga 通过创建 Sagas 将所有的异步操作逻辑收集在一个地方集中处理。Sagas 可以被看作是在后台运行的进程,监听发起的 action,然后决定基于这个 action 来做什么:是发起一个异步调用(比如一个 Ajax 请求),还是发起其他的 action 到 Store,甚至是调用其他的 Sagas。一旦出发 sagas 监听的 action,sagas 会通过一系列的effects dispatch (比如put
)一个 action。示例
redux-saga flow
VIEW dispatch 一个 ACTION object:
redux-saga vs redux-thunk
原理不同:Sagas 不同于 Thunks,Thunks 是在 action 被创建时调用,而 Sagas 会在应用启动时调用(但初始启动的 Sagas 可能会动态调用其他 Sagas),是常驻后台的(因为 generator)。
redux-saga 有cancel、takeLeast这些操作,这是 async 做不到的(这也是 generator 相对 async 的优势)
redux-saga 易测试,比如它可以无阻塞地调用一个 generator(fork)、中断一个 generator (cancel)。这些特性在业务逻辑复杂的场景下非常适用。测试代码详见这里
redux-saga 保持了 action 的原义,保持 action 的简洁,把所有有副作用的地方独立开来(这样action里会很干净)。这种特性让 redux-saga 在业务逻辑简单的场景下,也能保持代码清晰简洁。
redux-observable
code
你要先了解 rxjs ,然后再往下读。因为 redux-observable 就是让你能够在 Redux 中使用 rxjs。
为了方便理解 rxjs,我做了一个纯 js 版的项目 jsbin,之后能够我们再把它改成 react 版的。
redux-observable flow
Epic 是 redux-observable 的核心,它是一个函数,接收 actions 流作为参数并且返回 actions 流: Actions 入, actions 出。返回的 actions 会通过
store.dispatch()
立刻被分发,所以 redux-observable 实际上会做epic(action$, store).subscribe(store.dispatch)
。redux-observable vs redux-saga
可以看到,redux-observable 和 redux-saga 的数据流是相似的。关于他们的异同,可以查看这两篇文章,不再赘述:
mobx
code
先看一个 demo,它包含了
@action
@observable
@observer
@computed
@inject
等重要概念。MobX flow
MobX vs Redux
MobX vs Redux: Comparing the Opposing Paradigms 演讲已经介绍,不能看视频的看 MobX vs Redux: Comparing the Opposing Paradigms - React Conf 2017 纪要 也是可以的。
The text was updated successfully, but these errors were encountered: