Ant*_*ung 9 reactjs redux redux-thunk
我试图以下列方式将多个动作链接在一起:
A.将用户数据发布到数据库
B.使用发布的数据查询Elasticsearch的结果
(我并行做A和B)
B1.使用ES的结果,从两个表B2查询原始数据库的结果.导航到新页面并更新UI
我现在正在使用thunks来推断我的代码,但我也发现这个异步模式非常冗长:
export function fetchRecipes(request) {
return function(dispatch) {
dispatch(requestRecipes(request))
return fetch(url)
.then(response => response.json())
.then(json => dispatch(receiveRecipes(request, json))
)
}
}
Run Code Online (Sandbox Code Playgroud)
这个,以及"requestRecipes"和"receiveRecipes",因为其他动作创建者似乎只是为了进行一次异步调用.(请求,接收和获取功能)
总结:当你链接2-3个异步动作时,它们的输出相互依赖(我需要在可能的情况下进行宣传),是否有更有效的方法可以不为每个异步调用编写3个函数?
我认为必须要有办法.我是Redux文档的模式匹配,很快就被我正在创建的函数所淹没
非常感谢您的反馈!
您可以使用redux-saga而不是redux-thunk更容易实现这一目标.redux-saga让您使用生成器描述您的工作,更容易推理.
第一步是描述如何将数据传递给redux而不必担心服务或异步内容.
操作
// actions.js
function createRequestTypes(base) {
return {
REQUEST: base + "_REQUEST",
SUCCESS: base + "_SUCCESS",
FAILURE: base + "_FAILURE",
}
}
// Create lifecycle types on `RECIPES`
export const RECIPES = createRequestTypes("RECIPES")
// Create related actions
export const recipes = {
// Notify the intent to fetch recipes
request: request => ({type: RECIPES.REQUEST, request})
// Send the response
success: response => ({type: RECIPES.SUCCESS, response})
// Send the error
error: error => ({type: RECIPES.FAILURE, error})
}
Run Code Online (Sandbox Code Playgroud)
减速器
// reducer.js
import * as actions from "./actions"
// This reducer handles all recipes
export default (state = [], action) => {
switch (action.type) {
case actions.RECIPES.SUCCESS:
// Replace current state
return [...action.response]
case actions.RECIPES.FAILURE:
// Clear state on error
return []
default:
return state
}
}
Run Code Online (Sandbox Code Playgroud)
服务
我们还需要配方API.使用redux-saga最简单的方法声明服务时,就是创建一个(纯)函数,它将请求作为参数读取并返回一个Promise.
// api.js
const url = "https://YOUR_ENPOINT";
export function fetchRecipes(request) {
return fetch(url).then(response => response.json())
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要连接动作和服务.这是redux-saga发挥作用的地方.
// saga.js
import {call, fork, put, take} from "redux-saga/effects"
import * as actions from "./actions"
import * as api from "./api"
function* watchFetchRecipes() {
while (true) {
// Wait for `RECIPES.REQUEST` actions and extract the `request` payload
const {request} = yield take(actions.RECIPES.REQUEST)
try {
// Fetch the recipes
const recipes = yield call(api.fetchRecipes(request))
// Send a new action to notify the UI
yield put(actions.fetchRecipes.success(recipes))
} catch (e) {
// Notify the UI that something went wrong
yield put(actions.fetchRecipes.error(e))
}
}
}
function* rootSaga() {
yield [
fork(watchFetchRecipes)
]
}
Run Code Online (Sandbox Code Playgroud)
就是这样!每当组件发送一个RECIPES.REQUEST动作时,该传奇将挂钩并处理异步工作流.
dispatch(recipes.request(req))
Run Code Online (Sandbox Code Playgroud)
令人敬畏的redux-saga是,您可以在工作流程中轻松链接异步效果和分派操作.
| 归档时间: |
|
| 查看次数: |
3914 次 |
| 最近记录: |