我试图测试我的传奇可以遵循的每个场景,但我无法实现我想要的行为.这很简单,我有一个HTTP请求(登录),我想通过模拟我的API方法来测试成功和失败的情况.
但是,它看起来call effect
不会激活我的api功能,我还没有真正得到它是如何工作的,但我想中间件是负责调用该功能,因为我不去通过商店我的测试,我无法得到结果.
所以我的问题是,当您需要在异步调用旁边发送不同的操作(通常是成功或失败)时,如何测试您的传奇?
我找了一个例子,我发现sagas成功并失败但是失败案例从未经过测试,例如在这里的购物车示例中
SAGA.JS
export function* login(action) {
try {
const user = yield call(api.login, action);
return yield put(actions.loginSuccess(user));
} catch(e) {
yield put(actions.loginFail(e));
}
}
export default function* rootAuthenticationSagas() {
yield* takeLatest(LOGIN, login);
}
Run Code Online (Sandbox Code Playgroud)
TEST.JS
describe('login', () => {
context('When it fails', () => {
before('Stub the api', () => {
sinon.stub(api, 'login', () => {
// IT NEVER COMES HERE !
return Promise.reject({ error: 'user not found' });
});
});
it('should return …
Run Code Online (Sandbox Code Playgroud) 我正在关注有关帮助程序的redux-saga文档,到目前为止看起来非常简单,但是在执行api调用时我偶然发现了一个问题(因为你会看到文档的链接指向这样的例子)
有一部分Api.fetchUser
没有解释,因此我不清楚是否需要处理像axios或superagent这样的库?还是那个别的东西.和saga效果一样call, put
.等价的get, post
?如果是这样,他们为什么这样命名?基本上我正试图找出一种正确的方法来对我的api执行简单的post调用,example.com/sessions
并传递数据,如{ email: 'email', password: 'password' }
我在本例中使用react-redux和redux-saga进行API调用.我的目标是使用不同的URL进行另一个API调用,并在不同的页面中使用它们.怎么实现呢?
传奇故事:
import { take, put,call } from 'redux-saga/effects';
import { takeEvery, delay ,takeLatest} from 'redux-saga';
function fetchData() {
return fetch("https://api.github.com/repos/vmg/redcarpet/issues?state=closed")
.then(res => res.json() )
.then(data => ({ data }) )
.catch(ex => {
console.log('parsing failed', ex);
return ({ ex });
});
}
function* yourSaga(action) {
const { data, ex } = yield call(fetchData);
if (data)
yield put({ type: 'REQUEST_DONE', data });
else
yield put({ type: 'REQUEST_FAILED', ex });
}
export default function* watchAsync() {
yield* takeLatest('BLAH', yourSaga); …
Run Code Online (Sandbox Code Playgroud) 我尝试Unauthorized
使用redux-saga 处理来自服务器的错误.这是我的传奇:
function* logIn(action) {
try {
const user = yield call(Api.logIn, action);
yield put({type: types.LOG_IN_SUCCEEDED, user});
} catch (error) {
yield put({type: types.LOG_IN_FAILED, error});
}
}
Run Code Online (Sandbox Code Playgroud)
我获取这样的数据:
fetchUser(action) {
const {username, password} = action.user;
const body = {username, password};
return fetch(LOGIN_URL, {
method,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(body)
})
.then(res => {
res.json().then(json => {
if (res.status >= 200 && res.status < 300) {
return json
} else {
throw res
}
}) …
Run Code Online (Sandbox Code Playgroud) 我正在研究React&Redux项目.该项目过去常常使用webpack-dev-middleware和热中间件进行热重装.
在我将Redux Saga添加到项目中之后,将一些saga中间件添加到redux商店.似乎每当我更改传奇代码时,热重新加载都会破坏并显示错误消息:
提供商>不支持动态更改
store
.您很可能会看到此错误,因为您已更新到Redux 2.x和React Redux 2.x,它们不再自动热重新加载Reducer.有关迁移说明,请参阅https://github.com/reactjs/react-redux/releases/tag/v2.0.0.
我知道佐贺使用发电机并且它是时间依赖的.可以用Sagas热重新加载页面吗?就像Redux减速器在热重装过程中如何替换自身一样.
谢谢!
方案是,我想在调度操作后根据成功,错误回调重定向用户或显示警报.
下面是使用redux-thunk执行任务的代码
this.props.actions.login(credentials)
.then((success)=>redirectToHomePage)
.catch((error)=>alertError);
Run Code Online (Sandbox Code Playgroud)
因为redux-thunk中的调度操作返回一个Promise,所以很容易对响应起作用.
但是现在我在redux-saga上弄脏了,试图弄清楚如何能够获得与上面代码相同的结果.由于Saga在不同的线程上运行,我无法从上面的查询中获得回调.所以我只想知道你们是怎么做到的.或者什么是使用redux-saga时处理回调的最佳方法?调度操作如下所示:
this.props.actions.login(凭证);
和传奇
function* login(action) {
try {
const state = yield select();
const token = state.authReducer.token;
const response = yield call(API.login,action.params,token);
yield put({type: ACTION_TYPES.LOGIN_SUCCESS, payload:response.data});
yield call(setItem,AUTH_STORAGE_KEY,response.data.api_token);
} catch (error) {
yield put({type: ACTION_TYPES.LOGIN_FAILURE, error})
}
}
Run Code Online (Sandbox Code Playgroud)
传奇监视器
export function* loginMonitor() {
yield takeLatest(ACTION_TYPES.LOGIN_REQUEST,login);
}
Run Code Online (Sandbox Code Playgroud)
行动创造者
function login(params) {
return {
type: ACTION_TYPES.LOGIN_REQUEST,
params
}
}
Run Code Online (Sandbox Code Playgroud) 我正在努力让redux-saga与onmessage
听众合作.我不知道为什么我的工作不起作用.
我有以下设置.
// sagas.js
import { take, put } from 'redux-saga';
import {transactions} from "./actions";
function* foo (txs) {
console.log("yielding"); // appears in console
yield put(transactions(txs)); // action *is not* dispatched
console.log("yielded"); //appears in console
}
const onMessage = (event) => {
const txs = JSON.parse(event.data);
const iter = foo(txs);
iter.next(); // do I really need to do this?
};
function* getTransactions() {
while(yield take('APP_LOADED')) {
const stream = new EventSource(eventSourceUrl);
stream.onopen = onOpen;
stream.onmessage = onMessage;
stream.onerror …
Run Code Online (Sandbox Code Playgroud) 这是我的代码:
store.js
import {createStore, applyMiddleware, compose} from 'redux';
import {fromJS} from 'immutable';
import {routerMiddleware} from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import createReducer from './reducers';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [sagaMiddleware, routerMiddleware(history)];
const enhancers = [applyMiddleware(...middlewares)];
const store = createStore(createReducer, fromJS(initialState), enhancers);
// Extensions
store.runSaga = sagaMiddleware.run;
store.asyncReducers …
Run Code Online (Sandbox Code Playgroud) 因为回调中不允许"yield" - 语句,我如何在回调中使用redux-saga的"put"功能?
我想要进行以下回调:
function onDownloadFileProgress(progress) {
yield put({type: ACTIONS.S_PROGRESS, progress})
}
Run Code Online (Sandbox Code Playgroud)
这不起作用并以"意外令牌"结束,因为普通函数不允许产生.否则我不能将回调作为" 函数* " 传递,这将允许收益.ES6似乎在这里打破了.
我读过redux-saga提供了一些称为" 频道 "的功能,但说实话,我没有得到它.我已经多次阅读过关于这些频道和示例代码的内容,但在所有示例中,他们都解决了非常困难和不同的问题,而不是我的简单案例,并且在一天结束时我已经到了那里.
有人能告诉我如何处理这个问题的解决方案吗?
整个背景:
function onDownloadFileProgress(progress) {
yield put({type: ACTIONS.S_PROGRESS, progress})
}
export function * loadFile(id) {
let url = `media/files/${id}`;
const tempFilename = RNFS.CachesDirectoryPath + '/' + id;
const download = RNFS.downloadFile( {
fromUrl: url,
toFile: tempFilename,
background: false,
progressDivider: 10,
progress: onDownloadFileProgress,
})
yield download.promise;
}
Run Code Online (Sandbox Code Playgroud) redux-saga ×10
redux ×8
javascript ×6
reactjs ×6
ecmascript-6 ×2
react-redux ×2
api ×1
fetch ×1
generator ×1
webpack ×1
webpack-hmr ×1
yield ×1