使用 redux saga 时出错,take(patternOrChannel): argument 8 is not valid channel or a valid pattern

Posted

技术标签:

【中文标题】使用 redux saga 时出错,take(patternOrChannel): argument 8 is not valid channel or a valid pattern【英文标题】:Error using redux saga, take(patternOrChannel): argument 8 is not valid channel or a valid pattern 【发布时间】:2019-03-11 04:14:55 【问题描述】:

我正在尝试使用 redux saga 库来捕获一些操作,但在运行应用程序时出现此错误:

index.js:2178 未在 rootSaga 在 rootSaga 在 projectSaga 在 watchFetchRequest at takeEvery 错误:take(patternOrChannel): 参数 8 不是有效通道或有效模式 在采取 (http://localhost:3000/static/js/bundle.js:84689:9) attakeEvery (http://localhost:3000/static/js/bundle.js:85993:94) 在 createTaskIterator (http://localhost:3000/static/js/bundle.js:85179:17) 在 runForkEffect (http://localhost:3000/static/js/bundle.js:85583:24) 在 runEffect (http://localhost:3000/static/js/bundle.js:85468:872) 在下一个 (http://localhost:3000/static/js/bundle.js:85348:9) 在 proc (http://localhost:3000/static/js/bundle.js:85303:3) 在 runForkEffect (http://localhost:3000/static/js/bundle.js:85587:19) 在 runEffect (http://localhost:3000/static/js/bundle.js:85468:872) 在http://localhost:3000/static/js/bundle.js:85677:14 在 Array.forEach () 在 runAllEffect (http://localhost:3000/static/js/bundle.js:85676:10) 在 runEffect (http://localhost:3000/static/js/bundle.js:85468:413) 在下一个 (http://localhost:3000/static/js/bundle.js:85348:9) 在 proc (http://localhost:3000/static/js/bundle.js:85303:3) 在 runForkEffect (http://localhost:3000/static/js/bundle.js:85587:19) 在 runEffect (http://localhost:3000/static/js/bundle.js:85468:872) 在http://localhost:3000/static/js/bundle.js:85677:14 在 Array.forEach () 在 runAllEffect (http://localhost:3000/static/js/bundle.js:85676:10) 在 runEffect (http://localhost:3000/static/js/bundle.js:85468:413) 在下一个 (http://localhost:3000/static/js/bundle.js:85348:9) 在 proc (http://localhost:3000/static/js/bundle.js:85303:3) 在 runSaga (http://localhost:3000/static/js/bundle.js:85858:76) 在 Object../src/store/ReduxRoot.tsx (http://localhost:3000/static/js/bundle.js:95823:16) 在 webpack_require (http://localhost:3000/static/js/bundle.js:679:30) 在 fn (http://localhost:3000/static/js/bundle.js:89:20) 在 Object../src/index.tsx (http://localhost:3000/static/js/bundle.js:95325:75) 在 webpack_require (http://localhost:3000/static/js/bundle.js:679:30) 在 fn (http://localhost:3000/static/js/bundle.js:89:20) 在 Object.0 (http://localhost:3000/static/js/bundle.js:96424:18) 在 webpack_require (http://localhost:3000/static/js/bundle.js:679:30) 在 ./node_modules/@babel/runtime/helpers/arrayWithoutHoles.js.module.exports (http://localhost:3000/static/js/bundle.js:725:37) 在http://localhost:3000/static/js/bundle.js:728:10

这是传奇代码:

import  all, call, fork, put, takeEvery  from 'redux-saga/effects';
import   ActionType, Action, SearchCriteria  from '../model/types';
import  searchProjectsError, searchProjectsCompleted  from '../actions/projects';
import  API_URL  from '../../config';
// import axios from 'axios';

function callApi(method: string, url: string, path: string, data?: any) 
    return fetch(url  + path, 
      method,
      headers: 'Content-Type': 'application/json; charset=utf-8', 'Access-Control-Allow-Origin': '*',
      body: JSON.stringify(data)
    ).then(res => res.json());
  

// Here we use `redux-saga` to trigger actions asynchronously. `redux-saga` uses something called a
// "generator function", which you can read about here:
// https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Statements/function*

function* handleFetch(action: Action<SearchCriteria>) 
  try 
    // To call async functions, use redux-saga's `call()`.
    const res = yield call(callApi, 'get', API_URL , '/api/DocumentLoader/GetProjects/', action.payload);

    if (res.error) 
      yield put(searchProjectsError(res.error));
     else 
      yield put(searchProjectsCompleted(res));
    
   catch (err) 
    if (err instanceof Error) 
      yield put(searchProjectsError(err.stack!));
     else 
      yield put(searchProjectsError('An unknown error occured.'));
    
  


// This is our watcher function. We use `take*()` functions to watch Redux for a specific action
// type, and run our saga, for example the `handleFetch()` saga above.
function* watchFetchRequest() 
  yield takeEvery(ActionType.SEARCH_PROJECTS, handleFetch); // I think the error is here


// We can also use `fork()` here to split our saga into multiple watchers.
function* projectSaga() 
  yield all([fork(watchFetchRequest)]);


export default projectSaga;

我已经尝试在 SO 中找到答案,但我唯一能找到的是 this post,但 ActionType 已被导出。我认为问题出在handleFetch函数的参数上

这是动作:

export function searchProjects(criterias: SearchCriteria): Action<SearchCriteria> 
    return 
        type: ActionType.SEARCH_PROJECTS,
        payload: criterias
    ;

另一件事可能是我当时在编写 saga 中间件时做错了什么:

const sagaMiddleware = createSagaMiddleware();

var middleware = applyMiddleware(logger, thunk, sagaMiddleware);

if (process.env.NODE_ENV === 'development') 
    middleware = composeWithDevTools(middleware);


// Here we use `redux-saga` to trigger actions asynchronously. `redux-saga` uses something called a
// "generator function", which you can read about here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
export function* rootSaga() 
    yield all([fork(projectSaga)]);
  
// running the root saga, and return the store object.
 sagaMiddleware.run(rootSaga);

我还尝试从handleFetch 中删除操作参数,但错误仍在发生

【问题讨论】:

我已经更新了我的答案,看看吧! 这能回答你的问题吗? Redux-saga get data from action returns patternOrChannel is undefined 【参考方案1】:

我发现了错误,问题是ActionType枚举的定义。它没有为每个操作分配一个字符串值。

export const enum ActionType 

// Projects
SEARCH_PROJECT,
SEARCH_PROJECTS_COMPLETED,
SEARCH_PROJECTS_ERROR,


这解决了问题:

export const enum ActionType 

// Projects
SEARCH_PROJECTS= '@@projects/SEARCH_PROJECTS',
SEARCH_PROJECTS_COMPLETED= '@@projects/SEARCH_PROJECTS_COMPLETED',
SEARCH_PROJECTS_ERROR= '@@projects/SEARCH_PROJECTS_ERROR',


【讨论】:

一般来说,错误是没有将action常量赋值给字符串的结果。【参考方案2】:

唯一可能的错误可能是:

检查您是否在此处从定义常量的模型文件中导入了 ActionType 对象。

export function searchProjects(criterias: SearchCriteria): 
    Action<SearchCriteria> 
    return 
        type: ActionType.SEARCH_PROJECTS,
        payload: criterias
    ;

【讨论】:

但这不是我在 watchFetchRequest 函数中所做的吗? 对不起,这是我的错误。我没有注意到那部分代码。我会尽力想出解决方案。 关于您的更新,请查看显示导入的行:import ActionType, Action, SearchCriteria from '../model/types'; 您还必须在具有 searchProjects 操作的文件中导入 ActionType。 ActionType 必须在两个文件中导入。 我也在这样做,我正在使用打字稿,如果是那种错误,打字稿会让我知道

以上是关于使用 redux saga 时出错,take(patternOrChannel): argument 8 is not valid channel or a valid pattern的主要内容,如果未能解决你的问题,请参考以下文章

相当于 Redux thunks 中的收益 Take Redux Saga

redux store 安装 redux-saga 后创建 store 时出错

react redux Reduc-saga实现 take put takeEvery createSagaMiddleware等

redux-saga基本用法

redux-saga常用api概述

使用 redux saga 时等待 redux action 完成调度