Giter Site home page Giter Site logo

redux-saga-beginner-tutorial's Introduction

Redux Logo Landscape

redux-saga

npm version CDNJS npm Discord Shield OpenCollective OpenCollective

redux-saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, easy to test, and better at handling failures.

The mental model is that a saga is like a separate thread in your application that's solely responsible for side effects. redux-saga is a redux middleware, which means this thread can be started, paused and cancelled from the main application with normal redux actions, it has access to the full redux application state and it can dispatch redux actions as well.

It uses an ES6 feature called Generators to make those asynchronous flows easy to read, write and test. (if you're not familiar with them here are some introductory links) By doing so, these asynchronous flows look like your standard synchronous JavaScript code. (kind of like async/await, but generators have a few more awesome features we need)

You might've used redux-thunk before to handle your data fetching. Contrary to redux thunk, you don't end up in callback hell, you can test your asynchronous flows easily and your actions stay pure.

Getting started

Install

$ npm install redux-saga

or

$ yarn add redux-saga

Alternatively, you may use the provided UMD builds directly in the <script> tag of an HTML page. See this section.

Usage Example

Suppose we have a UI to fetch some user data from a remote server when a button is clicked. (For brevity, we'll just show the action triggering code.)

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

The Component dispatches a plain Object action to the Store. We'll create a Saga that watches for all USER_FETCH_REQUESTED actions and triggers an API call to fetch the user data.

sagas.js

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

// worker Saga: will be fired on USER_FETCH_REQUESTED actions
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 })
  }
}

/*
  Starts fetchUser on each dispatched `USER_FETCH_REQUESTED` action.
  Allows concurrent fetches of user.
*/
function* mySaga() {
  yield takeEvery('USER_FETCH_REQUESTED', fetchUser)
}

/*
  Alternatively you may use takeLatest.

  Does not allow concurrent fetches of user. If "USER_FETCH_REQUESTED" gets
  dispatched while a fetch is already pending, that pending fetch is cancelled
  and only the latest one will be run.
*/
function* mySaga() {
  yield takeLatest('USER_FETCH_REQUESTED', fetchUser)
}

export default mySaga

To run our Saga, we'll have to connect it to the Redux Store using the redux-saga middleware.

main.js

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

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

// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(reducer, applyMiddleware(sagaMiddleware))

// then run the saga
sagaMiddleware.run(mySaga)

// render the application

Documentation

Translation

Using umd build in the browser

There is also a umd build of redux-saga available in the dist/ folder. When using the umd build redux-saga is available as ReduxSaga in the window object. This enables you to create Saga middleware without using ES6 import syntax like this:

var sagaMiddleware = ReduxSaga.default()

The umd version is useful if you don't use Webpack or Browserify. You can access it directly from unpkg.

The following builds are available:

Important! If the browser you are targeting doesn't support ES2015 generators, you must transpile them (i.e. with babel plugin) and provide a valid runtime, such as the one here. The runtime must be imported before redux-saga:

import 'regenerator-runtime/runtime'
// then
import sagaMiddleware from 'redux-saga'

Building examples from sources

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

Below are the examples ported (so far) from the Redux repos.

Counter examples

There are three counter examples.

counter-vanilla

Demo using vanilla JavaScript and UMD builds. All source is inlined in index.html.

To launch the example, open index.html in your browser.

Important: your browser must support Generators. Latest versions of Chrome/Firefox/Edge are suitable.

counter

Demo using webpack and high-level API takeEvery.

$ npm run counter

# test sample for the generator
$ npm run test-counter

cancellable-counter

Demo using low-level API to demonstrate task cancellation.

$ npm run cancellable-counter

Shopping Cart example

$ npm run shop

# test sample for the generator
$ npm run test-shop

async example

$ npm run async

# test sample for the generators
$ npm run test-async

real-world example (with webpack hot reloading)

$ npm run real-world

# sorry, no tests yet

TypeScript

Redux-Saga with TypeScript requires DOM.Iterable or ES2015.Iterable. If your target is ES6, you are likely already set, however, for ES5, you will need to add it yourself. Check your tsconfig.json file, and the official compiler options documentation.

Logo

You can find the official Redux-Saga logo with different flavors in the logo directory.

Redux Saga chooses generators over async/await

A few issues have been raised asking whether Redux saga plans to use async/await syntax instead of generators.

We will continue to use generators. The primary mechanism of async/await is Promises and it is very difficult to retain the scheduling simplicity and semantics of existing Saga concepts using Promises. async/await simply don't allow for certain things - like i.e. cancellation. With generators we have full power over how & when effects are executed.

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]

License

Copyright (c) 2015 Yassine Elouafi.

Licensed under The MIT License (MIT).

redux-saga-beginner-tutorial's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-saga-beginner-tutorial's Issues

Error running incrementAsync test

I've copied the test content, and it fails when I run it:

incrementAsync Saga test

/srv/http/redux-saga-beginner-tutorial/sagas.spec.js:16
var gen = (0, _sagas.incrementAsync)();
^

TypeError: (0 , _sagas.incrementAsync) is not a function
at Test. (/srv/http/redux-saga-beginner-tutorial/sagas.spec.js:8:15)
at Test.bound [as _cb] (/srv/http/redux-saga-beginner-tutorial/node_modules/tape/lib/test.js:64:32)
at Test.run (/srv/http/redux-saga-beginner-tutorial/node_modules/tape/lib/test.js:83:10)
at Test.bound [as run] (/srv/http/redux-saga-beginner-tutorial/node_modules/tape/lib/test.js:64:32)
at Immediate.next (/srv/http/redux-saga-beginner-tutorial/node_modules/tape/lib/results.js:71:15)
at runCallback (timers.js:756:18)
at tryOnImmediate (timers.js:717:5)
at processImmediate [as _immediateCallback] (timers.js:697:5)

Reason for that is that we are not exporting the function, like:

export function* incrementAsync()

See, the tutorial took ride of the export directive when it introduced rootSaga() concept.

https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

import { delay } from 'redux-saga'
import { put, takeEvery, all } from 'redux-saga/effects'


function* incrementAsync() {
  yield delay(1000)
  yield put({ type: 'INCREMENT' })
}


function* watchIncrementAsync() {
  yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}


// notice how we now only export the rootSaga
// single entry point to start all Sagas at once
export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ])
}

So, if you guys wanna test the function, export it.

export function* incrementAsync() {
  yield delay(1000)
  yield put({ type: 'INCREMENT' })
}

notice at gitbook add 'all' effect

2018-03-08 16 46 06

please notice import 'all' from 'redux-saga/effects'

sagas.js
import { put, call, takeEvery } from 'redux-saga/effects'
=>
import { put, call, takeEvery, all } from 'redux-saga/effects'

Delay Counter

Nice tutorial, minor issue with the modification to the component change for the async increment. The tutorial gives this replacement, losing the value={store.getState()} which was necessary for display purposes.

function render() {
  ReactDOM.render(
    <Counter
      onIncrementAsync={() => action('INCREMENT_ASYNC')}
    />,
    document.getElementById('root')
  )
}

Inconsistency with the beginner tutorial

At Beginner Tutorial, In the initial setup section It is written that

If things go well, you should see 2 buttons Increment and Decrement along with a message below showing Counter: 0

but in the project it is "Clicked: 0 times" instead of "Counter: 0".

Not a big thing but yeah inconsistent with the tutorial.

执行npm run test时报错:Error: call: argument fn is undefined or null

执行npm run test时报错:Error: call: argument fn is undefined or null

image

如下修改代码就正常了

image

import test from 'tape';

// import { delay } from 'redux-saga'
import { put, call , delay} from 'redux-saga/effects'
import { incrementAsync } from './sagas'

test('incrementAsync Saga test', (t) => {
  const generator = incrementAsync()

  t.deepEqual(
    generator.next().value,
    // call(delay, 1000),
    delay(1000),
    'counter Saga must call delay(1000)'
  )

  t.deepEqual(
    generator.next().value,
    put({type: 'INCREMENT'}),
    'counter Saga must dispatch an INCREMENT action'
  )

  t.deepEqual(
    generator.next(),
    { done: true, value: undefined },
    'counter Saga must be done'
  )

  t.end()
});

Delay issue

Hi I clicked on "Increment after 1 sec" and I got error of delay
Screenshot 2020-04-30 at 8 21 30 PM

TypeError: (0 , _utils.delay) is not a function

I followed the tutorial to add asynchronous calls. However, I got this error in browser console,

 at rootSaga 
 at takeEvery 
 at incrementAsync 
 TypeError: (0 , _utils.delay) is not a function
    at incrementAsync$ (http://9.181.95.220:9966/build.js:31683:35)
    at tryCatch (http://9.181.95.220:9966/build.js:221:40)
    at Generator.invoke [as _invoke] (http://9.181.95.220:9966/build.js:459:22)
    at Generator.prototype.(anonymous function) [as next] (http://9.181.95.220:9966/build.js:273:21)
    at next (http://9.181.95.220:9966/build.js:29398:27)
    at proc (http://9.181.95.220:9966/build.js:29350:3)
    at runForkEffect (http://9.181.95.220:9966/build.js:29696:19)
    at runEffect (http://9.181.95.220:9966/build.js:29476:472)
    at digestEffect (http://9.181.95.220:9966/build.js:29555:5)

I figured out that in sagas.js, it should be import { delay } from 'redux-saga', instead of import { delay } from 'redux-saga/utils'. But from redux-saga/redux-saga#1401, delay is either in redux-saga/utils or redux-saga/effects, what is expected place to import delay?

Errors in Chinese documents

There is something wrong in Chinese document

export function* watchIncrementAsync() {
yield* takeEvery('INCREMENT_ASYNC', incrementAsync)
}

It should be

export function* watchIncrementAsync() {
yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}

what is this url http://10.42.0.1:9966

Hello you guy i just start learn about redux-saga .when i run the project
Server running at http://10.42.0.1:9966/ (connect)
why it not run on my localhost and where is this code from ?

Thank you

To avoid a RegExp DoS issue

When I clone this repo.
I just run 'npm install'.
but pop message below:

  • npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue

So, modify babel-core version to 6.25.0.
The message's gone.
I also create Pull request.

Have a nice day!

Filename typo for testfile in intro

According to the intro the file name for testing should be saga.spec.jsbut in package.jsonthe test command is provided as "test": "babel-node sagas.spec.js | tap-spec",.

FIX: either upd. intro readme.md filename to sagas.spec.js or upd package.json test to "test": "babel-node saga.spec.js | tap-spec",.

No biggie, just a typo :)

Wrong url in the server output

After starting the app we're presented with :

$ npm start

> [email protected] start /Users/sasklacz/Work/OSS/sagas-experiment
> budo main.js:build.js --dir ./ --verbose  --live -- -t babelify

[0001] info  Server running at http://10.192.128.156:9966/ (connect)
[0001] info  LiveReload running on 35729

where we should get localhost:9966 instead.

Unused action 'INCREMENT_IF_ODD'

There is an unused action INCREMENT_IF_ODD in the reducers.js file. Can you please remove this so that it does not cause any confusion.

Tutorial gives error on npm start

  1. Cloned the Repo
  2. Went inside the folder
  3. Did npm install
  4. Did npm start

Tried this on master and sagas branch, got the same error on both of them

Got following error on console and in the chrome when went to the server url

Plugin 20 specified in "/Users/XXX/redux-saga-beginner-tutorial/node_modules/babel-preset-es2015/lib/index.js" provided an invalid property of "name" while parsing file: /Users/XXX/redux-saga-beginner-tutorial/main.js

Error Cannot read property '_renderedComponent' of undefined

Hi guys,

I have implement redux-saga with type INCREMENT_ASYNC, but when I click on button Increment after 1 second, I received error message below:
Error

Look like I have an undefined here:
undefined

This is my code:

sagas.js

import { delay } from 'redux-saga'
import { put, takeEvery, all, call } from 'redux-saga/effects'

export function* helloSaga() {
  console.log('Hello Saga!')
}
// Our worker Saga: will perform the async increment task
export function* incrementAsync() {
  yield call(delay, 1000)
  yield put({ type: 'INCREMENT '})
}

// Our watcher Saga: spawn a new incrementAsync task on each INCREMENT_ASYNC
export function* watchIncrementAsync() {
  yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}

export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ])
}

main.js

import "babel-polyfill"

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'

import Counter from './Counter'
import reducer from './reducers'
import rootSaga from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)

const action = type => store.dispatch({type})

function render() {
  ReactDOM.render(
    <Counter
      value={store.getState()}
      onIncrement={() => action('INCREMENT')}
      onDecrement={() => action('DECREMENT')}
      onIncrementAsync={() => action('INCREMENT_ASYNC')} />,
    document.getElementById('root')
  )
}

render()
store.subscribe(render)

Counter.js

/*eslint-disable no-unused-vars */
import React, { Component, PropTypes } from 'react'

const Counter = ({ value, onIncrement, onDecrement, onIncrementAsync }) =>
      <div>
        <button onClick={onIncrementAsync}>
          Increment after 1 second
        </button>
        {' '}
        <button onClick={onIncrement}>
          Increment
        </button>
        {' '}
        <button onClick={onDecrement}>
          Decrement
        </button>
        <hr />
        <div>
          Clicked: {value} times
        </div>
      </div>

Counter.propTypes = {
  value: PropTypes.number.isRequired,
  onIncrement: PropTypes.func.isRequired,
  onDecrement: PropTypes.func.isRequired
}

export default Counter

reducers.js

export default function counter(state = 0, action) {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'INCREMENT_IF_ODD':
      return (state % 2 !== 0) ? state + 1 : state
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

Could you please tell me missing something here?
Thanks all,

ReferenceError: [BABEL]

ReferenceError: [BABEL] C:\tuto\redux-saga-beginner-tutorial\main.js: Unknown option: C:\tuto\redux-saga-beginner-tutorial\node_modules\babel-preset-env\lib\index.js.__esModule while parsing file: C:\tuto\redux-saga-beginner-tutorial\main.js

Please delete this issue

Please delete issue, I didn't realize the app was running without forcefully opening the browser.

npm WARN deprecated

npm WARN deprecated [email protected]: 🙌 Thanks for using Babel: we re commend using babel-preset-env now: please read babeljs.io/env to update!
npm WARN deprecated [email protected]: Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue

Code in the beginner tutorial does not match the finished code in sagas and doesn't work

The code in the tutorial does not execute properly. Pressing the async increment button has no effect.

The problem is that the tutorial specifies adding this code:

// notice how we now only export the rootSaga
// single entry point to start all Sagas at once
export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ])
}

The sagas branch has the correct code:

// notice how we now only export the rootSaga
// single entry point to start all Sagas at once
export default function* rootSaga() {
  yield [
    helloSaga(),
    watchIncrementAsync()
  ]
}

```utils.js:240 uncaught at check runSaga(storeInterface, saga, ...args): saga argument must be a Generator function! log @ utils.js:240 check @ utils.js:44 runSaga @ runSaga.js:31 2../Counter @ main.js:18 o @ _prelude.js:1 r @ _prelude.js:1 (anonymous) @ _prelude.js:1 utils.js:45 Uncaught Error: runSaga(storeInterface, saga, ...args): saga argument must be a Generator function! at check (utils.js:45) at runSaga (runSaga.js:31) at Object.2../Counter (main.js:18) at o (_prelude.js:1) at r (_prelude.js:1) at _prelude.js:1 check @ utils.js:45 runSaga @ runSaga.js:31 2../Counter @ main.js:18 o @ _prelude.js:1 r @ _prelude.js:1 (anonymous) @ _prelude.js:1```

Error while trying to run 2 sagas at a time

npm start运行错误

clone之后,npm install完成,执行npm start 就报错了。
$ npm start

[email protected] start E:\code\my\React\redux-saga-beginner- tutorial
budo main.js:build.js --dir ./ --verbose --live -- -t babelify

'budo' ▒▒▒▒▒ڲ▒▒▒▒ⲿ▒▒▒Ҳ▒▒▒ǿ▒▒▒▒еij▒▒▒
▒▒▒▒▒▒▒▒▒ļ▒▒▒

npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\ node_modules\npm\bin\npm-cli.js" "start"
npm ERR! node v4.0.0
npm ERR! npm v2.14.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: budo main.js:build.js --dir ./ --verbose --live -- -t babelify
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script 'budo mai n.js:build.js --dir ./ --verbose --live -- -t babelify'.
npm ERR! This is most likely a problem with the redux-saga-beginner-tutorial pac kage,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! budo main.js:build.js --dir ./ --verbose --live -- -t babelify
npm ERR! You can get their info via:
npm ERR! npm owner ls redux-saga-beginner-tutorial
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! E:\code\my\React\redux-saga-beginner-tutorial\npm-debug.log

关于 watchIncrementAsync 事件注册

我看英文文档,关于 watchIncrementAsync 的注册,使用的 sagaMiddleware.run(watchIncrementAsync ),同时我使用 createSagaMiddleware(watchIncrementAsync ) 是无效的。
请问,是调用方法变更了吗?

error in test

error in the following test:

assert.deepEqual( gen.next().value, call(delay, 1000), 'incrementAsync Saga must call delay(1000)' )

this gen.next().value return a promise as value:

{ value: Promise { _c: [], _a: undefined, _s: 0, _d: false, _v: undefined, _h: 0, _n: false, '@@redux-saga/cancelPromise': [Function] }, done: false }

So the test fail

error in helloSaga tutorial

the tutorial :

const store = createStore(
  reducer,
  applyMiddleware(createSagaMiddleware(helloSaga))
)

cause a error :
middleware.js:27Uncaught Error: You passed a function to the Saga middleware. You are likely trying to start a Saga by directly passing it to the middleware. This is no longer possible starting from 0.10.0. To run a Saga, you must do it dynamically AFTER mounting the middleware into the store.

so I change to:

const sagaMiddleware = createSagaMiddleware()
const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(helloSaga)

npm start fails

8 info [email protected] Failed to exec start script
9 verbose stack Error: [email protected] start: `budo main.js:build.js --dir ./ --verbose  --live -- -t babelify`
9 verbose stack spawn ENOENT
9 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:17:16)
9 verbose stack     at emitTwo (events.js:87:13)
9 verbose stack     at ChildProcess.emit (events.js:172:7)
9 verbose stack     at maybeClose (internal/child_process.js:827:16)
9 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
10 verbose pkgid [email protected]
11 verbose cwd /Users/bep/dev/clone/redux-saga-beginner-tutorial
12 error Darwin 16.1.0
13 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
14 error node v4.4.3
15 error npm  v2.15.1
16 error file sh
17 error code ELIFECYCLE
18 error errno ENOENT
19

saga argument must be a Generator function! error

I have code that was working fine until I upgrade the okta-react to 3.0.1 and now I am getting this weird error runSaga(options, saga, ...args): saga argument must be a Generator function!

  10 | export const store = createStore(rootReducer, getInitialState(), composeWithDevTools(applyMiddleware(sagaMiddleware)));
  11 | 
> 12 | sagaMiddleware.run(rootSaga);
     |                ^
  and my root saga is 

export const rootSaga = function* root() {
yield all([
fork(watchNewGeneratedNetworkRequestStart),
fork(watchGetRefsStartSaga),
fork(watchCommercialOrderSearch),
fork(watchSessionNetworkSaga),
fork(watchMissingCopySearch),
fork(watchMissingCopyRefSaga),
fork(watchAddInstruction),
fork(watchMediaSearches),
fork(watchLockSagas),
fork(watchSharedCommercialOrderSearch),
fork(watchMultiOrderInstructionSagas),
fork(watchLogPageSagas),
]);
};

any idea why I started having this errors after the update?

all is not defined

In section "Making Asynchronous calls" :

export default function* rootSaga() {
  yield all([
    helloSaga(),
    watchIncrementAsync()
  ])
}

Q: It throw an error as follow

uncaught at rootSaga 
ReferenceError: all is not defined

The saga version is ^0.15.0,
how can I solve this question? thanks.

This site can't be reached

> [email protected] start /Users/mherold/git/temp/redux-saga-beginner-tutorial
> budo main.js:build.js --dir ./ --verbose  --live -- -t babelify

[0000] info  Server running at http://10.174.92.194:9966/ (connect)
[0000] info  LiveReload running on 35729
[0005] 4202ms     2.4MB (browserify)

If I navigate to http://10.174.92.194:9966/, Chrome returns "This site can’t be reached"

If I navigate to localhost:35729, I get the following.

// 20170125171035
// http://localhost:35729/

{
  "tinylr": "Welcome",
  "version": "0.2.1"
}

Neither appears to have console output or a counter. Not certain what I'm missing.

TypeError: (0 , _effects.takeEvery) is not a function

There is no takeEvery in redux-saga/lib/effects being exported, it exports from the redux-saga/lib/index.js. But the documentation states that is should be gotten from 'redux-saga/lib/effects' like import { takeEvery } from 'redux-saga/effects. That is confusing.

uncaught at rootSaga 
 at rootSaga 
 TypeError: (0 , _effects.takeEvery) is not a function
    at watchIncrementAsync$ (http://127.0.0.1:9966/build.js:26627:41)
    at tryCatch (http://127.0.0.1:9966/build.js:195:40)
    at GeneratorFunctionPrototype.invoke [as _invoke] (http://127.0.0.1:9966/build.js:463:22)
    at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (http://127.0.0.1:9966/build.js:228:21)
    at next (http://127.0.0.1:9966/build.js:24756:27)
    at proc (http://127.0.0.1:9966/build.js:24715:3)
    at resolveIterator (http://127.0.0.1:9966/build.js:24891:5)
    at runEffect (http://127.0.0.1:9966/build.js:24873:97)
    at http://127.0.0.1:9966/build.js:25103:14
    at Array.forEach (native)
// sagas.js
import { delay } from 'redux-saga'
import { put, takeEvery } from 'redux-saga/effects'

export function* helloSaga() {
  console.log('Hello saga'); 
}

export function* incrementAsync() {
  yield delay(1000)
  yield put({ type: 'INCREMENT' })
}

export function* watchIncrementAsync() {
  yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}

export default function* rootSaga() {
  yield [ helloSaga(), watchIncrementAsync() ]
}
// main.js
import "babel-polyfill"

import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import rootSaga from './sagas'

import Counter from './Counter'
import reducer from './reducers'

const sagaMiddleware = createSagaMiddleware()

const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
)

sagaMiddleware.run(rootSaga)

const action = type => store.dispatch({ type })

function render() {
  ReactDOM.render(
    <Counter
      value={store.getState()}
      onIncrement={() => action('INCREMENT')}
      onDecrement={() => action('DECREMENT')}
      onIncrementAsync={() => action('INCREMENT_ASYNC')}
    />,
    document.getElementById('root')
  )
}

render()
store.subscribe(render)

UPD
I don't that is the reason of such behaviour, but after I completely removed and installed the module the issue has gone. 🤔

How to improve the beginner tutorial documentation?

Sorry if this is already somewhere else, I didn't see see a CONTRIBUTING file.

I am following:
https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html

I think the following suggestions would improve this documentation and project.

  1. In The initial setup, the section quoted below should include a link directly to the sagas branch here on GitHub. e.g.

    The final code of this tutorial is located in the `sagas` branch.
    

    This might help avoid what appear to be unnecessary future PRs like #28

  2. I would have found the Making Asynchronous calls section easier to follow, if it had told me to modify the Counter UI component in the Counter.js file.

  3. I didn't see any ESLint, prettier or similar file indicating what style guide is being followed, hence:

  4. The Making our code testable section has a redundant semicolon on line 1 (and also on line 13 after the test), e.g.

     import test from 'tape';
                            ^
    
  5. It would be nice if the expected npm test output was also shown:

redux-saga-beginner-tutorial$ npm test

> [email protected] test /Users/pzrq/Projects/redux-saga-beginner-tutorial
> babel-node sagas.spec.js | tap-spec


  incremmentAsync Saga test

    ✔ incrementAsync Saga must call delay(1000)
    ✔ incrementAsync Saga must dispatch an INCREMENT action
    ✔ incrementAsync Saga must be done


  total:     3
  passing:   3
  duration:  1.4s

Incorrect delay import in saga.spec.js

It's one of the final snippets in tutorial (saga.spec.js).
It should be

import { delay } from 'redux-saga'
import { put, call } from 'redux-saga/effects'
import { incrementAsync } from './sagas'

Tutorial fails on `delay` not defined

Following tutorial on http://yelouafi.github.io/redux-saga/docs/introduction/BeginnerTutorial.html , below code cannot actually initialize delay since it is not exported from redux-saga

import { takeEvery, delay } from 'redux-saga'

It throws exception when run npm test

/Users/morgan.cheng/github/redux-saga-beginner-tutorial/node_modules/babel-cli/node_modules/babel-polyfill/node_modules/babel-regenerator-runtime/runtime.js:511
        throw exception;
        ^

TypeError: (0 , _reduxSaga.delay) is not a function
    at incrementAsync$ (sagas.js:12:9)

error when with export default funcion in 1.1 beginnerTutorial

An issue because you export like default function and show the following error:
check sagaMiddleware.run(saga, ...args): saga argument must be a Generator function!

export default function* rootSaga() { yield [ helloSaga(), watchIncrementAsync() ] }

you need change to:

export function* rootSaga() { yield [ helloSaga(), watchIncrementAsync() ] }

react-projects/redux-saga-beginner-tutorial/reducers.js ENOSPC

After cloning and installing repo when I run npm run I got

[0002] info  Server running at http://172.18.0.1:9966/ (connect)
[0002] info  LiveReload running on 35729
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: watch /home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/reducers.js ENOSPC
    at _errnoException (util.js:1022:11)
    at FSWatcher.start (fs.js:1382:19)
    at Object.fs.watch (fs.js:1408:11)
    at createFsWatchInstance (/home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/node_modules/chokidar/lib/nodefs-handler.js:37:15)
    at setFsWatchListener (/home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/node_modules/chokidar/lib/nodefs-handler.js:80:15)
    at FSWatcher.NodeFsHandler._watchWithNodeFs (/home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/node_modules/chokidar/lib/nodefs-handler.js:228:14)
    at FSWatcher.NodeFsHandler._handleFile (/home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/node_modules/chokidar/lib/nodefs-handler.js:255:21)
    at FSWatcher.<anonymous> (/home/sufian/PROJECTS/react-projects/redux-saga-beginner-tutorial/node_modules/chokidar/lib/nodefs-handler.js:473:21)
    at FSReqWrap.oncomplete (fs.js:153:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `budo main.js:build.js --dir ./ --verbose  --live -- -t babelify`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/sufian/.npm/_logs/2018-07-20T08_35_29_667Z-debug.log

what to do?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.