使用 React/Redux saga 将数据从组件传递到 action 和 saga
Posted
技术标签:
【中文标题】使用 React/Redux saga 将数据从组件传递到 action 和 saga【英文标题】:Pass data from component to action and saga using React/Redux saga 【发布时间】:2018-08-04 21:03:09 【问题描述】:我将 React 与 Redux Saga 一起使用。当我尝试使用 this.props.dispatch(type: CreateActionType.CREATE_ASYNC); 在我的组件中执行传奇效果时什么都没有发生,它没有被执行。
当我在 index.js 中 console.log this.props.data 时,它是空的
如果此处缺少必要信息,请告诉我。
api.js
export const create = (params) =>
const dataList =
data: data1: 1, data2: 2,,
statusCode: 200,
return dataList;
;
sagas.js
import put, call, takeEvery , all from 'redux-saga/effects'
import create from '../api';
import * as CreateActionType from './constants';
export function* createAsync(action)
const result = yield call(create, action.params);
const statusCode = result.statusCode;
if (statusCode === 200)
yield [
put( type: CreateActionType.CREATE_SUCCESS, params: result.data ),
];
else
console.warn("createAsync error", result.data);
;
function* WatchCreate()
yield [
takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
]
export default function* rootSaga()
yield all([
WatchCreate(),
])
store.js
import * as CreateActionType from './constants';
import combineReducers from 'redux';
const defaultState =
data: null,
function CreateStore(state = defaultState, action)
switch (action.type)
case CreateActionType.CREATE_SUCCESS:
return
...state,
createStatus: true,
;
default:
return state;
;
const rootReducer = combineReducers(
CreateStore,
)
export default rootReducer;
index.js
import React, Component from 'react';
import connect from 'react-redux';
import * as CreateActionType from './constants';
class CreateNote extends Component
constructor(props)
super(props);
this.state = ;
;
componentDidMount()
this.props.dispatch(
type: CreateActionType.CREATE_ASYNC,
);
;
render()
return <p>this.props.data</p>;
const mapStateToProps = (state) =>
return state.CreateStore;
;
export default connect(mapStateToProps)(CreateNote);
configstore.js
import createStore, applyMiddleware from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootSaga from './container/sagas';
import rootReducer from './container/stores';
export default function ConfigureStore()
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer,
applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(rootSaga);
return store;
【问题讨论】:
创建代码sn-p并分享,你会得到更多反馈 这是基本的 redux 传奇 你应该调试它。如果控制台中没有错误消息,请添加一些 console.log 调用以查看执行与否。 您越容易为他人提供帮助,就越有可能帮助您。 【参考方案1】:很难判断出了什么问题,因为代码非常多。
假设 saga 实际正在运行,您永远不会对返回的数据做任何事情,这就解释了为什么 this.props.data
为空。你可以试试这个。
case CreateActionType.CREATE_SUCCESS:
return
...state,
createStatus: true,
data: action.params.data,
;
如果您不确定 sagas 是否正在运行,您应该在 api.js 和 sagas.js 中添加一些日志调用。
我看不出 sagas 不起作用的任何原因,但您可以尝试进一步简化它。我认为产生效果数组与产生单一效果相比没有任何好处。
export default function* rootSaga()
yield takeEvery(CreateActionType.CREATE_ASYNC, createAsync)
【讨论】:
@Lid 我有来自 api.js 的数据,我用 componentWillReceiveProps(nextProps) this.setState(content: nextProps.data); 固定在 index.js 。谢谢。 为什么要为此使用组件状态?您正在使用 redux。在 redux 中保持状态并在组件中使用 props 要简单得多。【参考方案2】:试着简化一下
function* WatchCreate()
yield [
takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
]
export default function* rootSaga()
yield all([
WatchCreate(),
])
到
export default function* rootSaga()
yield all([
takeEvery(CreateActionType.CREATE_ASYNC, createAsync),
])
我发现尽可能多地处理效果级别(同步创建的对象)而不是嵌套的 sagas 更容易。
您的问题可能是您调用WatchCreate
并尝试使用返回值,尽管它没有。
【讨论】:
@NguyễnThànhNam Mh。我注意到您还将put
放在一个数组中,这是不必要的。所以你是说你的状态仍然有 null ?你检查过你所有的 sagas 都被断点/调试器调用了吗?您是否在开发工具中看到所有预期的操作?【参考方案3】:
你的动作传奇有一个论点createAsync(action)
。调用函数时需要传递数据,例如takeEvery(createActionType.CREATE_ASYNC, createAsync, action)
。以下面这个例子为例。
import call, put, SagaReturnType, takeLatest from '@redux-saga/core/effects'
import axios, AxiosResponse from 'axios'
import * as ActionCreators from './actionCreators'
import * as ActionTypes from './actionTypes'
type apiResponse = SagaReturnType<typeof deleteUser>
const deleteUser = async (userId: string): Promise<AxiosResponse> =>
return axios.delete(`localhost:8081/users/$userId`)
function* deleteUserSaga(user: User)
try
if (user.userId)
const response: apiResponse = yield call(deleteUser, user.userId)
if (response.status === 200)
put(ActionCreators.deleteSuccess(user))
throw new Error('User delete unsuccessful')
catch (err)
put(ActionCreators.deleteError(err))
// eslint-disable-next-line
export default function* DeleteUserWatcher(user: User)
yield takeLatest(ActionTypes.DELETE_BEGIN, deleteUserSaga, user)
【讨论】:
以上是关于使用 React/Redux saga 将数据从组件传递到 action 和 saga的主要内容,如果未能解决你的问题,请参考以下文章
访问 saga 中的 store.dispatch 以与 react router redux 一起使用
react / redux / sagas - 如何基于现有商店数据链接动作?
react + redux + saga +服务器端渲染+如何停止服务器端渲染页面的额外ajax调用?