我正在使用redux和react路由器创建通用响应应用程序。我有大多数应用程序设置与服务器端呈现和基本redux操作(修改存储中的布尔值)。现在我想做一些api调用来获取我的应用程序的数据。
我认为使用redux-api-middleware是个好主意,但我无法将数据添加到商店。我按照文档编写了一个看起来像这样的动作。
import { CALL_API } from `redux-api-middleware`;
export function fn_get_data () {
[CALL_API]: {
endpoint: 'http://www.example.com/api/users',
method: 'GET',
types: ['REQUEST', 'SUCCESS', 'FAILURE']
}
}
我在页面上点击按钮运行此操作。我看到动作被解雇但没有任何东西进入商店。我甚至为SUCCESS
操作添加了一些自定义代码,并且能够console.log()
响应,但仍然无法将数据存入商店。
此外,我已经按照文档所说的相同方式将中间件添加到商店。
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { apiMiddleware } from 'redux-api-middleware';
import reducers from './reducers';
const reducer = combineReducers(reducers);
const createStoreWithMiddleware = applyMiddleware(apiMiddleware)(createStore);
export default function configureStore(initialState) {
return createStoreWithMiddleware(reducer, initialState);
}
到目前为止,我已经尝试了一系列不同的操作,例如将操作转换为可导出符号并在reducer中调用它们并尝试将数据合并到来自payload
属性的当前状态在redux-api-middleware中,但没有运气。
我真的有两个问题
对此事的任何帮助,解释或建设性批评都非常感谢,谢谢。
答案 0 :(得分:2)
据我所知,redux-api-middleware
提供了一系列用于进行API调用,调度成功/失败操作以及可能稍微处理响应的工具。但是,如何在Reducer中处理这些操作取决于您。因此,如果您要求中间件调度"MY_REQUEST_SUCCESS"
,则需要在reducer逻辑中添加"MY_REQUEST_SUCCESS"
处理程序,并相应地更新状态。
答案 1 :(得分:2)
像markerikson所说,该库只为您提供工具,您仍然需要编写reduceres来响应操作。在我的情况下,我终于得到了以下减速器的数据。
import * as ExampleActionType from "../action/example-action";
import Immutable from "immutable";
let defaultState = Immutable.fromJS({
fakeData: {}
});
function exampleState (state = defaultState, action) {
switch (action.type) {
case ExampleActionType.REQUEST : {
console.log(action);
return state;
}
case ExampleActionType.SUCCESS : {
console.log(action);
return state.merge({fakeData: action.payload });
}
case ExampleActionType.FAILURE : {
console.log(action);
return state;
}
default:
return state;
}
}
我还必须像这样输出符号
export const REQUEST = Symbol('REQUEST');
export const SUCCESS = Symbol('SUCCESS');
export const FAILURE = Symbol('FAILURE');
非常棒的库,它为您提供了使用非常少的代码创建api请求所需的所有工具。希望这能帮助那些对此感到困惑的人,就像我一样。
答案 2 :(得分:0)
redux-api-middleware
并不意味着将数据存储到商店(这就是为什么您不需要设置任何减速器的原因)。我实际上建立了一个库redux-cached-api-middleware,该库充当redux-api-middleware
之上的薄层,并增加了缓存(可以很容易地用作简单存储)功能。
这是一个示例组件:
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import api from 'redux-cached-api-middleware';
import Items from './Items';
import Error from './Error';
class ExampleApp extends React.Component {
componentDidMount() {
this.props.fetchData();
}
render() {
const { result } = this.props;
if (!result) return null;
if (result.fetching) return <div>Loading...</div>;
if (result.error) return <Error data={result.errorPayload} />;
if (result.successPayload) return <Items data={result.successPayload} />;
return <div>No items</div>;
}
}
ExampleApp.propTypes = {
fetchData: PropTypes.func.isRequired,
result: PropTypes.shape({}),
};
const CACHE_KEY = 'GET/items';
const enhance = connect(
state => ({
result: api.selectors.getResult(state, CACHE_KEY),
}),
dispatch => ({
fetchData() {
return dispatch(
api.actions.invoke({
method: 'GET',
headers: { Accept: 'application/json' },
endpoint: 'https://my-api.com/items/',
cache: {
key: CACHE_KEY,
strategy: api.cache
.get(api.constants.CACHE_TYPES.TTL_SUCCESS)
.buildStrategy({ ttl: 10 * 60 * 1000 }), // 10 minutes
},
})
);
},
})
);
export default enhance(ExampleApp);
这项工作以缓存方式进行,但是您可以轻松地传递自定义shouldFetch
函数,并且始终可以从API进行重新提取:
const enhance = connect(
state => ({
result: api.selectors.getResult(state, CACHE_KEY),
}),
dispatch => ({
fetchData() {
return dispatch(
api.actions.invoke({
method: 'GET',
headers: { Accept: 'application/json' },
endpoint: 'https://my-api.com/items/',
cache: {
key: CACHE_KEY,
shouldFetch: () => true
},
})
);
},
})
);
设置如下(注意api reducer,它实际上处理了存储对redux状态的响应):
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { apiMiddleware } from 'redux-api-middleware';
import api from 'redux-cached-api-middleware';
import reducers from './reducers';
const store = createStore(
combineReducers({
...reducers,
[api.constants.NAME]: api.reducer,
}),
applyMiddleware(thunk, apiMiddleware)
);