Redux Thunk - 异步,使用 Promises 链接操作
Redux Thunk - Async, chaining actions with Promises
所以最近两天我一直被这个问题难住了。
所以在应用程序中,有多个组织。我还有一个允许用户在组织之间切换的操作。
组织减速机:
import {
FETCH_ORGANIZATION_LIST_REQUEST,
FETCH_ORGANIZATION_LIST_SUCCESS,
ORGANIZATION_ERROR,
PICK_ORGANIZATION } from '../actions/types'
const INITIAL_STATE = { error: null, organizations: [], isFetching: false, currentOrganization: null, hasCurrentOrganization: false };
export default function (state = INITIAL_STATE, action) {
switch (action.type){
case FETCH_ORGANIZATION_LIST_REQUEST:
return { ...state, isFetching: action.isFetching, error: null};
case FETCH_ORGANIZATION_LIST_SUCCESS:
return { ...state, isFetching: action.isFetching, organizations: action.payload, error: null };
case ORGANIZATION_ERROR:
return { ...state, isFetching: action.isFetching, error: action.payload };
case PICK_ORGANIZATION:
return { ...state, currentOrganization: action.organizationId, hasCurrentOrganization: action.hasCurrentOrganization };
default:
return state
}
}
fetch组织和pick组织调用如下:
export function fetchOrganizationList() {
const url = `/organizations`;
return (dispatch) => getData(
FETCH_ORGANIZATION_LIST_REQUEST,
FETCH_ORGANIZATION_LIST_SUCCESS,
ORGANIZATION_ERROR,
true,
url,
dispatch);
};
export function pickOrganization(organizationId) {
return (dispatch) => {
dispatch({
type: PICK_ORGANIZATION,
organizationId: organizationId,
hasCurrentOrganization: true
})
}
};
我有一个 getData 调用,它也用于其他服务器调用:
export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
const requestUrl = API_URL + url;
let headers = {};
dispatch({
type: actionRequest,
isFetching: true,
error: null
});
if(isAuthReq) {
headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
}
axios.get(requestUrl, headers)
.then((response) => {
dispatch({
type: actionSuccess,
isFetching: false,
payload: response.data
});
return response.data;
})
.catch((error) => {
errorHandler(dispatch, error, errorType)
})
}
最后我有一个 OrganizationSelector.jsx 容器组件,它允许我挑选当前组织。
import React, {
Component,
PropTypes,
} from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchOrganizationList, pickOrganization, fetchAndPickCurrentOrganization } from '../../actions/organizations';
import Picker from '../../components/Picker';
class OrganizationSelector extends Component {
componentDidMount() {
this.props.fetchOrganizationList();
}
render() {
const { isFetching, error, organizations, dispatch } = this.props;
let count = !isFetching ? organizations.count : 1;
return (
<div>
{isFetching && !error &&
<li>Loading...</li>}
{!isFetching && !error && count > 1 &&
<Picker
currentOrganization={organizations.results[0].name}
options={organizations.results}
onSubmit={pickOrganization()}
/>
}
{!isFetching && !error && count === 1 &&
<div>
{organizations.results[0].name}
</div>
}
</div>
);
}
}
OrganizationSelector.propTypes = {};
OrganizationSelector.defaultProps = {};
const mapStateToProps = state => ({
organizations: state.organization.organizations,
isFetching: state.organization.isFetching,
error: state.organization.error
});
function mapDispatchToProps(dispatch) {
return {
fetchOrganizationList: bindActionCreators(fetchOrganizationList, dispatch),
// pickOrganization: bindActionCreators(pickOrganization, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(OrganizationSelector);
现在我遇到的问题是在同一个动作中将动作链接在一起 creator.I 想在 fetchOrganizationList 动作完成提取后传递 picOrganization 动作,我尝试做一些事情,通过 fetchListAndPickCurrentOrganization () 函数。
export function fetchListAndPickCurrentOrganization() {
return (dispatch) => {
dispatch(fetchOrganizationList())
.then(response => {
console.log(response) // This is where the Pick organization call will go
})
.catch(() => {
console.log('error')
})
}
};
我也尝试直接在 fetchOrganizationList() 调用中进行 axios 调用,但我一直将 .then 视为未定义,我猜这是因为 axios 调用返回的响应没有传递到.然后.
我已经尝试了很多东西,但目标是 运行 在第一次安装应用程序时调用这两个调用,当然会再次使用 pickOrganization 调用在组织之间切换。
所以解决方案非常简单,我不得不 return axios.get 请求,因为它没有在我的初始解决方案中得到 returned,这就是为什么什么都没有传递给 .then,它是未定义的。
export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
const requestUrl = API_URL + url;
let headers = {};
dispatch({
type: actionRequest,
isFetching: true,
error: null
});
if(isAuthReq) {
headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
}
return axios.get(requestUrl, headers)
.then((response) => {
dispatch({
type: actionSuccess,
isFetching: false,
payload: response.data
});
return response.data;
})
.catch((error) => {
errorHandler(dispatch, error, errorType)
})
}
谢谢@Ashley 'CptLemming' Wilson 帮我解决了这个问题。
所以最近两天我一直被这个问题难住了。
所以在应用程序中,有多个组织。我还有一个允许用户在组织之间切换的操作。
组织减速机:
import {
FETCH_ORGANIZATION_LIST_REQUEST,
FETCH_ORGANIZATION_LIST_SUCCESS,
ORGANIZATION_ERROR,
PICK_ORGANIZATION } from '../actions/types'
const INITIAL_STATE = { error: null, organizations: [], isFetching: false, currentOrganization: null, hasCurrentOrganization: false };
export default function (state = INITIAL_STATE, action) {
switch (action.type){
case FETCH_ORGANIZATION_LIST_REQUEST:
return { ...state, isFetching: action.isFetching, error: null};
case FETCH_ORGANIZATION_LIST_SUCCESS:
return { ...state, isFetching: action.isFetching, organizations: action.payload, error: null };
case ORGANIZATION_ERROR:
return { ...state, isFetching: action.isFetching, error: action.payload };
case PICK_ORGANIZATION:
return { ...state, currentOrganization: action.organizationId, hasCurrentOrganization: action.hasCurrentOrganization };
default:
return state
}
}
fetch组织和pick组织调用如下:
export function fetchOrganizationList() {
const url = `/organizations`;
return (dispatch) => getData(
FETCH_ORGANIZATION_LIST_REQUEST,
FETCH_ORGANIZATION_LIST_SUCCESS,
ORGANIZATION_ERROR,
true,
url,
dispatch);
};
export function pickOrganization(organizationId) {
return (dispatch) => {
dispatch({
type: PICK_ORGANIZATION,
organizationId: organizationId,
hasCurrentOrganization: true
})
}
};
我有一个 getData 调用,它也用于其他服务器调用:
export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
const requestUrl = API_URL + url;
let headers = {};
dispatch({
type: actionRequest,
isFetching: true,
error: null
});
if(isAuthReq) {
headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
}
axios.get(requestUrl, headers)
.then((response) => {
dispatch({
type: actionSuccess,
isFetching: false,
payload: response.data
});
return response.data;
})
.catch((error) => {
errorHandler(dispatch, error, errorType)
})
}
最后我有一个 OrganizationSelector.jsx 容器组件,它允许我挑选当前组织。
import React, {
Component,
PropTypes,
} from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchOrganizationList, pickOrganization, fetchAndPickCurrentOrganization } from '../../actions/organizations';
import Picker from '../../components/Picker';
class OrganizationSelector extends Component {
componentDidMount() {
this.props.fetchOrganizationList();
}
render() {
const { isFetching, error, organizations, dispatch } = this.props;
let count = !isFetching ? organizations.count : 1;
return (
<div>
{isFetching && !error &&
<li>Loading...</li>}
{!isFetching && !error && count > 1 &&
<Picker
currentOrganization={organizations.results[0].name}
options={organizations.results}
onSubmit={pickOrganization()}
/>
}
{!isFetching && !error && count === 1 &&
<div>
{organizations.results[0].name}
</div>
}
</div>
);
}
}
OrganizationSelector.propTypes = {};
OrganizationSelector.defaultProps = {};
const mapStateToProps = state => ({
organizations: state.organization.organizations,
isFetching: state.organization.isFetching,
error: state.organization.error
});
function mapDispatchToProps(dispatch) {
return {
fetchOrganizationList: bindActionCreators(fetchOrganizationList, dispatch),
// pickOrganization: bindActionCreators(pickOrganization, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(OrganizationSelector);
现在我遇到的问题是在同一个动作中将动作链接在一起 creator.I 想在 fetchOrganizationList 动作完成提取后传递 picOrganization 动作,我尝试做一些事情,通过 fetchListAndPickCurrentOrganization () 函数。
export function fetchListAndPickCurrentOrganization() {
return (dispatch) => {
dispatch(fetchOrganizationList())
.then(response => {
console.log(response) // This is where the Pick organization call will go
})
.catch(() => {
console.log('error')
})
}
};
我也尝试直接在 fetchOrganizationList() 调用中进行 axios 调用,但我一直将 .then 视为未定义,我猜这是因为 axios 调用返回的响应没有传递到.然后.
我已经尝试了很多东西,但目标是 运行 在第一次安装应用程序时调用这两个调用,当然会再次使用 pickOrganization 调用在组织之间切换。
所以解决方案非常简单,我不得不 return axios.get 请求,因为它没有在我的初始解决方案中得到 returned,这就是为什么什么都没有传递给 .then,它是未定义的。
export function getData( actionRequest, actionSuccess, errorType, isAuthReq, url, dispatch) {
const requestUrl = API_URL + url;
let headers = {};
dispatch({
type: actionRequest,
isFetching: true,
error: null
});
if(isAuthReq) {
headers = {headers: {'Authorization': 'Token ' + cookie.load('token')} }
}
return axios.get(requestUrl, headers)
.then((response) => {
dispatch({
type: actionSuccess,
isFetching: false,
payload: response.data
});
return response.data;
})
.catch((error) => {
errorHandler(dispatch, error, errorType)
})
}
谢谢@Ashley 'CptLemming' Wilson 帮我解决了这个问题。