请检查编辑
我正在尝试在我的应用程序中实现 sagas。
现在我正在以一种非常糟糕的方式获取道具。我的应用程序主要包括来自其他来源的轮询数据。
目前,这是我的应用程序的工作方式:
我有具有 mapStateToProps、mapDispatchToProps的容器。
const mapStateToProps = state => {
return {
someState: state.someReducer.someReducerAction,
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({someAction, someOtherAction, ...}, dispatch)
};
const something = drizzleConnect(something, mapStateToProps, mapDispatchToProps);
export default something;
然后,我有行动,像这样:
import * as someConstants from '../constants/someConstants';
export const someFunc = (someVal) => (dispatch) => {
someVal.methods.someMethod().call().then(res => {
dispatch({
type: someConstants.FETCH_SOMETHING,
payload: res
})
})
}
和reducers,如下所示:
export default function someReducer(state = INITIAL_STATE, action) {
switch (action.type) {
case types.FETCH_SOMETHING:
return ({
...state,
someVar: action.payload
});
我将减速器与 redux 的 combineReducers 结合起来,并将它们导出为单个减速器,然后将其导入我的商店。
因为我使用毛毛雨,所以我的 rootSaga 是这样的:
import { all, fork } from 'redux-saga/effects'
import { drizzleSagas } from 'drizzle'
export default function* root() {
yield all(
drizzleSagas.map(saga => fork(saga)),
)
}
所以,现在,当我想componentWillReceiveProps
在组件内部更新道具时,我会:
this.props.someAction()
好的,它有效,但我知道这不是正确的方法。基本上,这是我能做的最糟糕的事情。
所以,现在,我认为我应该做的是:
创建不同的 saga,然后将其导入到 rootSaga 文件中。这些 sagas 将每隔某个预定义的时间轮询一次源,并在需要时更新 props。
但我的问题是这些传奇应该如何写。
根据我上面提到的动作、reducers 和容器,你可以给我一个例子吗?
编辑:
我设法按照 apachuilo 的指示行事。
到目前为止,我做了以下调整:
动作是这样的:
export const someFunc = (payload, callback) => ({
type: someConstants.FETCH_SOMETHING_REQUEST,
payload,
callback
})
和减速器,像这样:
export default function IdentityReducer(state = INITIAL_STATE, {type, payload}) {
switch (type) {
case types.FETCH_SOMETHING_SUCCESS:
return ({
...state,
something: payload,
});
...
我还创建了一些Sagas:
...variousImports
import * as apis from '../apis/someApi'
function* someHandler({ payload }) {
const response = yield call(apis.someFunc, payload)
response.data
? yield put({ type: types.FETCH_SOMETHING_SUCCESS, payload: response.data })
: yield put({ type: types.FETCH_SOMETHING_FAILURE })
}
export const someSaga = [
takeLatest(
types.FETCH_SOMETHING_REQUEST,
someHandler
)
]
然后,更新了rootSaga:
import { someSaga } from './sagas/someSagas'
const otherSagas = [
...someSaga,
]
export default function* root() {
yield all([
drizzleSagas.map(saga => fork(saga)),
otherSagas
])
}
此外,api如下:
export const someFunc = (payload) => {
payload.someFetching.then(res => {
return {data: res}
}) //returns 'data' of undefined but just "return {data: 'something'} returns that 'something'
所以,我想更新我的问题:
我的 API 取决于商店的状态。正如你所理解的,我正在构建一个 dApp。因此,在调用 API 并将信息返回给组件之前,需要启动 Drizzle(我用来访问区块链的中间件)。因此,
一个。尝试使用 getState() 读取状态,返回空合同(尚未“准备好”的合同) - 所以我无法获取信息 - 我不喜欢从商店读取状态,但是......
湾。通过组件传递状态(this.props.someFunc(someState),返回给我
Cannot read property 'data' of undefined
有趣的是,我可以 console.log 状态(看起来没问题)并尝试返回 {data: 'someData'},道具正在接收数据。- 我应该在例如 componentWillMount() 上运行 this.props.someFunc() 吗?这是更新道具的正确方法吗?
对不起,很长的帖子,但我想准确。
编辑 1b:嗯,有很多编辑 :) 我用未定义的解决方案解决了这个问题。只需要像这样编写 API:
export function someFunc(payload) {
return payload.someFetching.then(res => {
return ({ data: res })
})
}