React Redux - 可能在调度函数中有一个回调
React Redux -possible to have a call back in dispatch function
伙计们,我遇到了一些麻烦或很怀疑。
我有一个组件和一个减速器。
Reducer.js
import {
ASSET_POPUP_GET_ENDPOINT,
} from 'apiCollection';
import { performGet } from 'services/rest-service/rest-service';
export const GET_ASSETS_LIST = 'stories/GET_ASSETS_LIST';
const initialState = {
imgGroup: [],
isLoading: false,
};
const modalUploadReducer = (state = initialState, action) => {
switch (action.type) {
case GET_ASSETS_LIST: {
return {
...state,
ImageJson:action.payload.imageGroup,
};
}
case GET_ASSETS_LIST_ERROR: {
return {
...state,
isLoading:false,
};
}
default:
return state;
}
};
export const getModalClose = () => (dispatch) => {
dispatch({ type: CLOSE_MODAL });
}
export const getListActionDispactcher = () => (dispatch) => {
performGet(`${ASSET_POPUP_GET_ENDPOINT}`)
.then((response) => {
const payload = response.data;
dispatch({ type: GET_ASSETS_LIST,
payload: {
...payload,
data: payload.results,
} });
})
.catch((err) => {
dispatch({ type: GET_ASSETS_LIST_ERROR, payload: err });
throw err;
});
};
export default modalUploadReducer;
我的组件看起来像
它确实有 mapStateToProps 和 mapDispatchToProps
和函数之一
const mapDispatchToProps = dispatch => ({
getCollection: () => dispatch(getListActionDispactcher()),
});
addDocumentClick = () =>{
this.props.getAssetsCollection();
}
并且在从组件中的 reducer 获得 api 响应后是否可能有一些 setState/manipulation 响应
根据响应,我需要对 addDocumentClick 进行一些更改。
意思是这样的
addDocumentClick = () =>{
this.props.getAssetsCollection().then(...based on response;
}
解决此问题的正确方法是设置一个全局 loading
标志并在您的 componentDidUpdate()
方法中检查该值以确定该操作刚刚成功。您似乎已经有了 isLoading
标志。只需在分派操作时设置它,然后取消设置 succeeds/fails。在 componentDidUpdate()
:
function componentDidUpdate(prevProps) {
if (prevProps.isLoading && !this.props.isLoading) {
// do something
}
}
当然,您需要connect()
您的组件加载标志才能实现此目的。
如果你只关心资产列表是否发生变化,你可以简单地检查componentDidUpdate()
中那个道具的变化:
function componentDidUpdate(prevProps) {
if (prevProps.ImageJson !== this.props.ImageJson) {
// do something
}
}
另一种解决方案是向您的操作调度程序发送回调,这会使您的代码更紧密地耦合,我不推荐,但它确实有效。所以,当你connect()
时,你可以:
getCollection: (onSuccess) => dispatch(getListActionDispactcher(onSuccess)),
在您的操作调度程序中:
export const getListActionDispactcher = (onSuccess) => (dispatch) => {
// ...once API finished/failed
onSuccess(someData);
}
最后,在您的组件中:
this.props.getCollection((result) => {
console.log('succeeded!', result);
// hide modal, etc..
}
您正在使用 redux-thunk,并且调用 thunk 将 return 一个 promise,它将解决您 return 在您的 thunk 中的任何问题。因此,您需要做的就是将 return 值添加到 getListActionDispactcher
export const getListActionDispactcher = () => (dispatch) => {
// return this promise
return performGet(`${ASSET_POPUP_GET_ENDPOINT}`)
.then((response) => {
const payload = response.data;
dispatch({ type: GET_ASSETS_LIST,
payload: {
...payload,
data: payload.results,
} });
// return whatever you want from promise
return payload
})
.catch((err) => {
dispatch({ type: GET_ASSETS_LIST_ERROR, payload: err });
throw err;
});
};
.
addDocumentClick = () => {
this.props.getAssetsCollection().then(payload => console.log(payload))
}
但是,为了模块化,您应该寻找避免这种模式的方法,让您的组件尽可能地与操作分离
伙计们,我遇到了一些麻烦或很怀疑。
我有一个组件和一个减速器。
Reducer.js
import {
ASSET_POPUP_GET_ENDPOINT,
} from 'apiCollection';
import { performGet } from 'services/rest-service/rest-service';
export const GET_ASSETS_LIST = 'stories/GET_ASSETS_LIST';
const initialState = {
imgGroup: [],
isLoading: false,
};
const modalUploadReducer = (state = initialState, action) => {
switch (action.type) {
case GET_ASSETS_LIST: {
return {
...state,
ImageJson:action.payload.imageGroup,
};
}
case GET_ASSETS_LIST_ERROR: {
return {
...state,
isLoading:false,
};
}
default:
return state;
}
};
export const getModalClose = () => (dispatch) => {
dispatch({ type: CLOSE_MODAL });
}
export const getListActionDispactcher = () => (dispatch) => {
performGet(`${ASSET_POPUP_GET_ENDPOINT}`)
.then((response) => {
const payload = response.data;
dispatch({ type: GET_ASSETS_LIST,
payload: {
...payload,
data: payload.results,
} });
})
.catch((err) => {
dispatch({ type: GET_ASSETS_LIST_ERROR, payload: err });
throw err;
});
};
export default modalUploadReducer;
我的组件看起来像
它确实有 mapStateToProps 和 mapDispatchToProps 和函数之一
const mapDispatchToProps = dispatch => ({
getCollection: () => dispatch(getListActionDispactcher()),
});
addDocumentClick = () =>{
this.props.getAssetsCollection();
}
并且在从组件中的 reducer 获得 api 响应后是否可能有一些 setState/manipulation 响应
根据响应,我需要对 addDocumentClick 进行一些更改。 意思是这样的
addDocumentClick = () =>{
this.props.getAssetsCollection().then(...based on response;
}
解决此问题的正确方法是设置一个全局 loading
标志并在您的 componentDidUpdate()
方法中检查该值以确定该操作刚刚成功。您似乎已经有了 isLoading
标志。只需在分派操作时设置它,然后取消设置 succeeds/fails。在 componentDidUpdate()
:
function componentDidUpdate(prevProps) {
if (prevProps.isLoading && !this.props.isLoading) {
// do something
}
}
当然,您需要connect()
您的组件加载标志才能实现此目的。
如果你只关心资产列表是否发生变化,你可以简单地检查componentDidUpdate()
中那个道具的变化:
function componentDidUpdate(prevProps) {
if (prevProps.ImageJson !== this.props.ImageJson) {
// do something
}
}
另一种解决方案是向您的操作调度程序发送回调,这会使您的代码更紧密地耦合,我不推荐,但它确实有效。所以,当你connect()
时,你可以:
getCollection: (onSuccess) => dispatch(getListActionDispactcher(onSuccess)),
在您的操作调度程序中:
export const getListActionDispactcher = (onSuccess) => (dispatch) => {
// ...once API finished/failed
onSuccess(someData);
}
最后,在您的组件中:
this.props.getCollection((result) => {
console.log('succeeded!', result);
// hide modal, etc..
}
您正在使用 redux-thunk,并且调用 thunk 将 return 一个 promise,它将解决您 return 在您的 thunk 中的任何问题。因此,您需要做的就是将 return 值添加到 getListActionDispactcher
export const getListActionDispactcher = () => (dispatch) => {
// return this promise
return performGet(`${ASSET_POPUP_GET_ENDPOINT}`)
.then((response) => {
const payload = response.data;
dispatch({ type: GET_ASSETS_LIST,
payload: {
...payload,
data: payload.results,
} });
// return whatever you want from promise
return payload
})
.catch((err) => {
dispatch({ type: GET_ASSETS_LIST_ERROR, payload: err });
throw err;
});
};
.
addDocumentClick = () => {
this.props.getAssetsCollection().then(payload => console.log(payload))
}
但是,为了模块化,您应该寻找避免这种模式的方法,让您的组件尽可能地与操作分离