首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Redux-Saga & Redux-Toolkit布线

Redux-Saga & Redux-Toolkit布线
EN

Stack Overflow用户
提问于 2021-01-21 05:47:00
回答 3查看 4.2K关注 0票数 1

我一直试图在我的项目中引入redux和redux工具包。看来我的线路有点问题。不知道该怎么解决。如果你有什么想法请告诉我。这是我正在犯的错误。下面是指向github的链接

文件- configureAppStore.js

代码语言:javascript
复制
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import reducer from './reducer';
import createSagaMiddleware from 'redux-saga';
import tweetSagas from '../saga/tweet.js';

const sagaMiddleware = createSagaMiddleware();
const middlewares = [sagaMiddleware];
const middleware = [...getDefaultMiddleware({ thunk: false }), ...middlewares];

const configureAppStore = () => {
  // reduxjs/toolkit configureStore enables to dispatch async actions
  return configureStore({
    reducer: reducer,
    middleware: middleware,
  });
};

sagaMiddleware.run(tweetSagas);

export default configureAppStore;

文件- saga/tweet.js

代码语言:javascript
复制
import { takeEvery, call, put, fork } from 'redux-saga/effects';
import axios from 'axios';
import * as actions from '../store/action/saga.js';
const port = process.env.REACT_APP_PORT;
const hostname = process.env.REACT_APP_LOCALHOST;
const baseURL = `http://${hostname}:${port}`;

function api({ dispatch }) {
  return function (next) {
    return function* (action) {
      if (action.type !== actions.sagaApiCallBegan.type) return next(action);
      next(action); // 'sagaApiCallBegan' to show in redux dev tools
      const { url, method, onSuccess, onError } = action.payload;
      try {
        const response = yield call(
          async () =>
            await axios.request({
              baseURL: baseURL,
              url,
              method,
            })
        );
        if (onSuccess)
          yield put(dispatch({ type: onSuccess, payload: response.data }));
      } catch (error) {
        if (onError) yield put(dispatch({ type: onError, payload: error }));
      }
    };
  };
}

function* watchApi() {
  yield takeEvery(actions.sagaApiCallBegan.type, api);
}

const tweetSagas = [fork(watchApi)];

export default tweetSagas;

文件- store/tweets.js

代码语言:javascript
复制
import { createSlice } from '@reduxjs/toolkit';
import {
  sagaApiCallBegan,
  sagaApiCallSuccess,
  sagaApiCallFailed,
} from './action/saga';
import { webSocketCallBegan, webSocketCallFailed } from './action/websocket.js';
import { normalize } from 'normalizr';
import { tweetSchema } from '../store/Schema/tweet.js';

const initialState = () => ({
  byTweetId: {},
  byUserId: {},
  allTweetIds: [],
});

// action, actionTypes and reducer
const slice = createSlice({
  name: 'tweets',
  initialState: initialState(),
  // reducers
  reducers: {
    tweetAdded: (state, action) => {
      const { entities, result } = normalize(action.payload, tweetSchema);
      Object.assign(state.byTweetId, entities.byTweetId);
      Object.assign(state.byUserId, entities.byUserId);
      state.allTweetIds.push(result);
    },
    tweetStoreReseted: (state) => initialState(),
  },
});

export const { tweetAdded, tweetStoreReseted } = slice.actions;
export default slice.reducer;

// Action creators
export const fetchTweets = (term) =>
  sagaApiCallBegan({
    url: `/setsearchterm/${term}`,
    method: 'get',
    onSuccess: sagaApiCallSuccess.type,
    onError: sagaApiCallFailed.type,
  });

export const fetchTweetsPause = () =>
  sagaApiCallBegan({
    url: '/pause',
    method: 'GET',
    onSuccess: sagaApiCallSuccess.type,
    onError: sagaApiCallFailed.type,
  });

export const getTweet = (message) =>
  webSocketCallBegan({
    message: message,
    onSuccess: tweetAdded.type,
    onError: webSocketCallFailed.type,
  });

文件- action/saga.js

代码语言:javascript
复制
import { createAction } from '@reduxjs/toolkit';

export const sagaApiCallBegan = createAction('saga/apiCallBegan');
export const sagaApiCallSuccess = createAction('saga/apiCallSuccess');
export const sagaApiCallFailed = createAction('saga/apiCallFailed');
EN

回答 3

Stack Overflow用户

发布于 2021-03-18 10:04:54

我创建并使用了允许异步块被sagas解析的saga-工具包

slice.js

代码语言:javascript
复制
import { createSlice } from '@reduxjs/toolkit'
import { createSagaAction  } from 'saga-toolkit'

const name = 'example'

const initialState = {
  result: null,
  loading: false,
  error: null,
}

export const fetchThings = createSagaAction(`${name}/fetchThings`)

const slice = createSlice({
  name,
  initialState,
  extraReducers: {
    [fetchThings.pending]: () => ({
      loading: true,
    }),
    [fetchThings.fulfilled]: ({ payload }) => ({
      result: payload,
      loading: false,
    }),
    [fetchThings.rejected]: ({ error }) => ({
      error,
      loading: false,
    }),
  },
})

export default slice.reducer

sagas.js

代码语言:javascript
复制
import { call } from 'redux-saga/effects'
import { takeLatestAsync } from 'saga-toolkit'
import API from 'hyper-super-api'
import * as actions from './slice'

function* fetchThings() {
  const result = yield call(() => API.get('/things'))
  return result
}

export default [
  takeLatestAsync(actions.fetchThings.type, fetchThings),
]
票数 2
EN

Stack Overflow用户

发布于 2021-01-21 06:23:48

我认为没有必要让您的存储配置成为一个函数,但是您应该确保在App.jsx文件中调用该函数。我不确定你是不是因为这里的代码丢失了。

以下是一些问题,我确实发现,这些问题是很容易解决的。

1 Redux sagas使用生成器

代码语言:javascript
复制
function api

要使这个函数正常工作,它必须是

代码语言:javascript
复制
function* api
  1. 优先考虑副作用功能而不是调度
代码语言:javascript
复制
dispatch(put({ ... })

您不需要使用dispatch。相反,使用put或其他副作用函数来调度事件。Put是一个阻塞的调度呼叫。所以这段代码应该是

传递put到调度也会在应用程序中造成错误,因为调度总是期望一个对象。

代码语言:javascript
复制
yield put({ ... })
  1. 根sagas也是生成器。
代码语言:javascript
复制
const tweetSagas = [fork(watchApi)];

在创建rootSaga时,需要在fork函数前面使用yield关键字。根传奇也是一个生成器函数,因此这段代码必须更改为以下代码。

代码语言:javascript
复制
export default function* tweetSagas () {
  yield fork(
    watchApi()
  )
}

您还必须在fork函数前面使用yield关键字。用sagas从生成器中返回值对您没有多大好处。

票数 1
EN

Stack Overflow用户

发布于 2021-01-22 00:35:40

这是答案

文件- configureAppStore.js

代码语言:javascript
复制
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import reducer from './reducer';
import toast from './middleware/toast.js';
import websocket from './middleware/websocket.js';
import createSagaMiddleware from 'redux-saga';
import tweetSagas from '../saga/tweet.js';

const configureAppStore = () => {
  const sagaMiddleware = createSagaMiddleware();

  const middlewares = [sagaMiddleware, websocket, toast];

  const middleware = [
    ...getDefaultMiddleware({ thunk: false }),
    ...middlewares,
  ];

  const store = configureStore({
    reducer: reducer,
    middleware: middleware,
  });

  sagaMiddleware.run(tweetSagas);

  return store;
};

export default configureAppStore;

文件- saga/tweet.js

代码语言:javascript
复制
import { takeEvery, call, put, fork } from 'redux-saga/effects';
import axios from 'axios';
import * as actions from '../store/action/saga.js';
const port = process.env.REACT_APP_PORT;
const hostname = process.env.REACT_APP_LOCALHOST;
const baseURL = `http://${hostname}:${port}`;

const fetchApi = async ({ baseURL, url, method }) =>
  await axios.request({
    baseURL: baseURL,
    url: url,
    method: method,
  });

function* api(action) {
  const { url, method, onSuccess, onError } = action.payload;
  const options = {
    baseURL: baseURL,
    url: url,
    method: method,
  };
  try {
    const response = yield call(fetchApi, options);
    if (onSuccess)
      yield put({
        type: onSuccess,
        payload: response.data,
      });
  } catch (error) {
    if (onError) yield put({ type: onError, payload: error });
  }
}

function* watchApi() {
  yield takeEvery(actions.sagaApiCallBegan.type, api);
}

export default function* tweetSagas() {
  yield fork(watchApi);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65821810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档