【发布时间】:2020-01-21 19:50:37
【问题描述】:
请检查编辑
我正在尝试在我的应用中实现 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
});
我将 reducer 与 redux 的 combineReducers 组合起来,并将它们作为单个 reducer 导出,然后将其导入我的 store。
因为我用的是毛毛雨,所以我的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。
但我的问题是如何编写这些 sagas。
可以根据我上面提到的action、reducer和container给我举个例子吗?
编辑:
我设法听从了阿帕楚洛的指示。
到目前为止,我做了以下调整:
动作如下:
export const someFunc = (payload, callback) => ({
type: someConstants.FETCH_SOMETHING_REQUEST,
payload,
callback
})
还有 reducers,像这样:
export default function IdentityReducer(state = INITIAL_STATE, {type, payload}) {
switch (type) {
case types.FETCH_SOMETHING_SUCCESS:
return ({
...state,
something: payload,
});
...
我还创建了 someSagas:
...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。所以,Drizzle(我按顺序使用的中间件 访问区块链),需要在我调用之前启动 API 并向组件返回信息。因此,
一个。尝试使用 getState() 读取状态,返回空合同 (尚未“准备好”的合同) - 所以我无法获取信息 - 我 不喜欢从商店读取状态,但是...
b.通过组件传递状态(this.props.someFunc(someState),返回我
Cannot read property 'data' of undefined有趣的是我可以console.log 状态(看起来还可以)并尝试仅返回 {data: 'someData'},props 正在接收数据。 - 我是否应该运行 this.props.someFunc(),例如 componentWillMount()?这是更新道具的正确方法吗?
抱歉,帖子太长了,但我想准确一点。
为 1b 编辑:呃,这么多编辑 :) 我用未定义的解决方案解决了这个问题。只需要像这样编写 API:
export function someFunc(payload) {
return payload.someFetching.then(res => {
return ({ data: res })
})
}
【问题讨论】:
标签: javascript reactjs react-redux redux-thunk drizzle