redux-api-middleware如何向store添加数据?
How does redux-api-middleware add data to the store?
背景
我正在使用 redux 和 react router 创建一个通用的 react 应用程序。我有大部分应用程序设置,包括服务器端渲染和基本的 redux 操作(修改商店中的布尔值)。现在我想进行一些 api 调用来为我的应用程序获取数据。
当前实施
我认为使用 redux-api-middleware 是个好主意,但我无法获取要添加到商店的数据。我按照文档创建了一个如下所示的操作。
示例-action.js
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()
响应但仍然无法将数据放入商店。
我还按照文档中说明的方式将中间件添加到商店中。
configureStore.js
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 中调用它们,并尝试将数据合并到来自 [=15= 的当前状态中] redux-api-中间件中的属性,但运气不好。
问题
我真的有2个问题
- 为什么文档中没有缩减器,这是被忽略了还是响应中的数据直接进入了存储?
- 为什么我调用的数据没有添加到商店(我缺少什么)?
非常感谢对此事的任何帮助、解释或建设性批评,谢谢。
据我所知,redux-api-middleware
提供了一系列工具来进行 API 调用、调度 success/failure 操作,并可能对响应进行一些处理。但是,您如何在 reducer 中处理这些操作取决于您。因此,如果您要求中间件分派 "MY_REQUEST_SUCCESS"
,您需要将 "MY_REQUEST_SUCCESS"
处理程序添加到您的 reducer 逻辑中,并适当地更新状态。
解决方案
就像markerikson说的,库只是给你提供工具,你还是要写reducer来响应action。就我而言,我终于通过以下减速器获得了数据。
示例-reducer.js
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;
}
}
我也不得不像这样导出符号
示例-action.js
export const REQUEST = Symbol('REQUEST');
export const SUCCESS = Symbol('SUCCESS');
export const FAILURE = Symbol('FAILURE');
结论
很棒的库,它为您提供了用很少的代码创建 api 请求所需的所有工具。希望这能帮助像我一样对此感到困惑的人。
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)
);
背景
我正在使用 redux 和 react router 创建一个通用的 react 应用程序。我有大部分应用程序设置,包括服务器端渲染和基本的 redux 操作(修改商店中的布尔值)。现在我想进行一些 api 调用来为我的应用程序获取数据。
当前实施
我认为使用 redux-api-middleware 是个好主意,但我无法获取要添加到商店的数据。我按照文档创建了一个如下所示的操作。
示例-action.js
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()
响应但仍然无法将数据放入商店。
我还按照文档中说明的方式将中间件添加到商店中。
configureStore.js
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 中调用它们,并尝试将数据合并到来自 [=15= 的当前状态中] redux-api-中间件中的属性,但运气不好。
问题
我真的有2个问题
- 为什么文档中没有缩减器,这是被忽略了还是响应中的数据直接进入了存储?
- 为什么我调用的数据没有添加到商店(我缺少什么)?
非常感谢对此事的任何帮助、解释或建设性批评,谢谢。
据我所知,redux-api-middleware
提供了一系列工具来进行 API 调用、调度 success/failure 操作,并可能对响应进行一些处理。但是,您如何在 reducer 中处理这些操作取决于您。因此,如果您要求中间件分派 "MY_REQUEST_SUCCESS"
,您需要将 "MY_REQUEST_SUCCESS"
处理程序添加到您的 reducer 逻辑中,并适当地更新状态。
解决方案
就像markerikson说的,库只是给你提供工具,你还是要写reducer来响应action。就我而言,我终于通过以下减速器获得了数据。
示例-reducer.js
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;
}
}
我也不得不像这样导出符号
示例-action.js
export const REQUEST = Symbol('REQUEST');
export const SUCCESS = Symbol('SUCCESS');
export const FAILURE = Symbol('FAILURE');
结论
很棒的库,它为您提供了用很少的代码创建 api 请求所需的所有工具。希望这能帮助像我一样对此感到困惑的人。
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)
);