最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to setup redux-sagas and file structure? - Stack Overflow

programmeradmin2浏览0评论

I am using React-native, axios after i learn how to install jwt and apply to my React native i see without state management i have to pass jwt token that fetch from login auth as props down multiple lvl that what i start hating. so i research and see about redux, redux-thunk, redux-saga and i choose redux-saga.

Can any guide me to setup redux-sagas like Folder structure, code split example i had 2 page like product, firmware.

in redux-thunk

action/
      /actionProduct.js
      /actionFirmware.js
reducer/
       /index.js
       /productReducer.js
       /firmwareReducer.js
store.js
index.js

but in redux-sagas i'm start to confuse it has action, reducer, sagas and store is difference setup too.

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

// then run the saga
sagaMiddleware.run(mySaga);
export default store;

in redux-thunk i never see simillar syntax like this sagaMiddleware.run(mySaga);

Do i need to create sagas folder and add 2 sagas like productSagas, firmwareSagas ?

Do i need to write 2 line like

sagaMiddleware.run(productSagas);
sagaMiddleware.run(firmwareSagas);
export default store;

or we can setup dynamic store ? and how can i do it ? Thank in advanced.


New Topic

i'm not sure i have setup this properly or not let see my setup. Store.js

const sagaMiddleware = createSagaMiddleware();
const store = createStore(
  rootReducer,
  window.devToolsExtension && process.env.NODE_ENV !== 'production' ?
  pose(
    applyMiddleware(sagaMiddleware),
    window.devToolsExtension(),
  ) :
  applyMiddleware(sagaMiddleware),
);

sagaMiddleware.run(rootSaga);

export default store;

rootSaga file

export default function* rootSaga() {
    yield all([
        firmwareWatcher(),
        productWatcher(),
    ]);
}

rootReducer

export default const rootReducer = bineReducers({
    firmware,
    porduct,
});

App.js

class App extends Component {
  ponentDidMount() {
    const { dispatch } = this.props; 
    dispatch({ type: "FIRMWARE_REQUEST"});
    dispatch({ type: 'PRODUCT_REQUEST'});
  }
....
}
const mapStateToProps = (state) => {
  console.log(state);
  return { ... };
};

this is console.log(state) inside mapStateToProps i get and i consone.log in switch case to know ACTION TYPE

    PRODUCT_SUCCESS
        {type: "PRODUCT_SUCCESS", payload: {…}, @@redux-saga/SAGA_ACTION: true}
        {firmware: {…}, porduct: {…}}
    FIRMWARE_SUCCESS
        {type: "API_CALL_SUCCESS", payload: {…}, @@redux-saga/SAGA_ACTION: true}
    default
        {firmware: {…}, porduct: {…}}
    {firmware: {…}, porduct: {…}}
  |
  V
firmware : {fetching: false, dog: null, error: null, data: "/api/img/retriever-golden/n02099601_2495.jpg"}
porduct :
    data : {id: 120, name: "A1", image: "a1_12-16-2017-1513389068.jpg", price: "28.00", status: 1, …}

I am using React-native, axios after i learn how to install jwt and apply to my React native i see without state management i have to pass jwt token that fetch from login auth as props down multiple lvl that what i start hating. so i research and see about redux, redux-thunk, redux-saga and i choose redux-saga.

Can any guide me to setup redux-sagas like Folder structure, code split example i had 2 page like product, firmware.

in redux-thunk

action/
      /actionProduct.js
      /actionFirmware.js
reducer/
       /index.js
       /productReducer.js
       /firmwareReducer.js
store.js
index.js

but in redux-sagas i'm start to confuse it has action, reducer, sagas and store is difference setup too.

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

// then run the saga
sagaMiddleware.run(mySaga);
export default store;

in redux-thunk i never see simillar syntax like this sagaMiddleware.run(mySaga);

Do i need to create sagas folder and add 2 sagas like productSagas, firmwareSagas ?

Do i need to write 2 line like

sagaMiddleware.run(productSagas);
sagaMiddleware.run(firmwareSagas);
export default store;

or we can setup dynamic store ? and how can i do it ? Thank in advanced.


New Topic

i'm not sure i have setup this properly or not let see my setup. Store.js

const sagaMiddleware = createSagaMiddleware();
const store = createStore(
  rootReducer,
  window.devToolsExtension && process.env.NODE_ENV !== 'production' ?
  pose(
    applyMiddleware(sagaMiddleware),
    window.devToolsExtension(),
  ) :
  applyMiddleware(sagaMiddleware),
);

sagaMiddleware.run(rootSaga);

export default store;

rootSaga file

export default function* rootSaga() {
    yield all([
        firmwareWatcher(),
        productWatcher(),
    ]);
}

rootReducer

export default const rootReducer = bineReducers({
    firmware,
    porduct,
});

App.js

class App extends Component {
  ponentDidMount() {
    const { dispatch } = this.props; 
    dispatch({ type: "FIRMWARE_REQUEST"});
    dispatch({ type: 'PRODUCT_REQUEST'});
  }
....
}
const mapStateToProps = (state) => {
  console.log(state);
  return { ... };
};

this is console.log(state) inside mapStateToProps i get and i consone.log in switch case to know ACTION TYPE

    PRODUCT_SUCCESS
        {type: "PRODUCT_SUCCESS", payload: {…}, @@redux-saga/SAGA_ACTION: true}
        {firmware: {…}, porduct: {…}}
    FIRMWARE_SUCCESS
        {type: "API_CALL_SUCCESS", payload: {…}, @@redux-saga/SAGA_ACTION: true}
    default
        {firmware: {…}, porduct: {…}}
    {firmware: {…}, porduct: {…}}
  |
  V
firmware : {fetching: false, dog: null, error: null, data: "https://dog.ceo/api/img/retriever-golden/n02099601_2495.jpg"}
porduct :
    data : {id: 120, name: "A1", image: "a1_12-16-2017-1513389068.jpg", price: "28.00", status: 1, …}
Share Improve this question edited Apr 8, 2018 at 9:58 Reaksmey asked Apr 7, 2018 at 3:53 ReaksmeyReaksmey 2052 gold badges7 silver badges16 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

You don't need to run the individual sagas, since you are using sagaMiddleware all your actions will pass through your sagas. I think you're on the right track - here is how I would set up sagas.

Create a saga for each of your async ponents, productSaga.js and firmwareSaga.js.

Then create an index file for your sagas index-sagas.js. This will import all the sagas from around your project and export them for use in your index.js file.

/// index-sagas.js ///
import productWatcher from './ponents/product/product-saga.js';
import firmwareWatcher from './ponents/firmware/firmware-saga.js';

export default function* IndexSagas() {
  yield [
    productWatcher(),
    firmwareWatcher(),
  ]
}
/// end of file ///

This is what you import at the top of index.js:

/// index.js ///
import IndexSagas from './index-sagas.js'

...

/// end of file ///

In product-saga.js and firmware-saga.js create a couple generator functions

/// product-saga.js ///
import { PRODUCT_ACTION } from './constants';
import { productActionSuccess, productActionError } from './actions';

export default function* productWatcher() {
  yield [
    takeLatest(PRODUCT_ACTION, productActionFlow)
  ]
} 
// This will be triggered any time PRODUCT_ACTION is dispatched and it
// will call the productActionFlow generator.  This is
// where your async logic lives  

function* productActionFlow(action) {
  try {
    const result = yield call(productGETRequest, action)
    // productGETRequest is a function elsewhere in this file that
    // will make your GET request
    yield put(productActionSuccess(result))
    // productActionSuccess is the action imported above
  } catch (error) {
    yield put(productActionError(error)
  }
}
发布评论

评论列表(0)

  1. 暂无评论