如何设置 redux-saga 和文件结构?

Rea*_*mey 6 javascript reactjs react-native redux-saga

在我学习如何安装 jwt 并应用于我的 React Native 后,我正在使用 React-native,axios 我看到没有状态管理我必须传递从登录身份验证获取的 jwt 令牌作为道具向下多个 lvl,我开始讨厌。所以我研究了一下,redux, redux-thunk, redux-saga然后选择了redux-saga

任何人都可以指导我设置 redux-sagas 之类的文件夹结构,代码拆分示例我有 2 页,如产品、固件。

在 redux-thunk 中

action/
      /actionProduct.js
      /actionFirmware.js
reducer/
       /index.js
       /productReducer.js
       /firmwareReducer.js
store.js
index.js
Run Code Online (Sandbox Code Playgroud)

但是在 redux-saga 中,我开始混淆它有 action、reducer、saga 和 store 也是不同的设置。

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

// then run the saga
sagaMiddleware.run(mySaga);
export default store;
Run Code Online (Sandbox Code Playgroud)

在 redux-thunk 中,我从未见过类似的语法 sagaMiddleware.run(mySaga);

我是否需要创建 sagas 文件夹并添加 2 个 sagas 像 productSagas、firmwareSagas ?

我需要写2行吗

sagaMiddleware.run(productSagas);
sagaMiddleware.run(firmwareSagas);
export default store;
Run Code Online (Sandbox Code Playgroud)

或者我们可以设置动态商店?我该怎么做?先谢谢了。


新话题

我不确定我是否正确设置了它或不让我看到我的设置。商店.js

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

sagaMiddleware.run(rootSaga);

export default store;
Run Code Online (Sandbox Code Playgroud)

rootSaga 文件

export default function* rootSaga() {
    yield all([
        firmwareWatcher(),
        productWatcher(),
    ]);
}
Run Code Online (Sandbox Code Playgroud)

rootReducer

export default const rootReducer = combineReducers({
    firmware,
    porduct,
});
Run Code Online (Sandbox Code Playgroud)

应用程序.js

class App extends Component {
  componentDidMount() {
    const { dispatch } = this.props; 
    dispatch({ type: "FIRMWARE_REQUEST"});
    dispatch({ type: 'PRODUCT_REQUEST'});
  }
....
}
const mapStateToProps = (state) => {
  console.log(state);
  return { ... };
};
Run Code Online (Sandbox Code Playgroud)

这是我得到的 mapStateToProps 中的 console.log(state) 并且我在 switch case 中使用 consone.log 来了解 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, …}
Run Code Online (Sandbox Code Playgroud)

Luc*_*ner 4

您不需要运行单独的 sagas,因为您使用的是 sagaMiddleware,您的所有操作都将通过您的 sagas。我认为你走在正确的道路上 - 这就是我如何设置传奇。

为每个异步组件创建一个传奇,productSaga.js并且firmwareSaga.js.

然后为您的 sagas 创建一个索引文件index-sagas.js。这将从您的项目中导入所有传奇并将其导出以在您的index.js文件中使用。

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

export default function* IndexSagas() {
  yield [
    productWatcher(),
    firmwareWatcher(),
  ]
}
/// end of file ///
Run Code Online (Sandbox Code Playgroud)

这是您在顶部导入的内容index.js

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

...

/// end of file ///
Run Code Online (Sandbox Code Playgroud)

创建几个生成器product-saga.js函数firmware-saga.js

/// 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)
  }
}
Run Code Online (Sandbox Code Playgroud)