【问题标题】:How does redux-api-middleware add data to the store?redux-api-middleware 是如何向 store 添加数据的?
【发布时间】:2016-11-03 21:14:26
【问题描述】:

背景

我正在使用 redux 和 react 路由器创建一个通用的 react 应用程序。我的大部分应用程序设置都带有服务器端渲染和基本的 redux 操作(在商店中修改布尔值)。现在我想调用一些 api 来为我的应用获取数据。

当前实施

我认为使用 redux-api-middleware 是个好主意,但我无法将数据添加到存储中。我按照文档创建了一个看起来像这样的操作。

example-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 中调用它们,并尝试将数据合并到来自 redux 中 payload 属性的当前状态-api-middleware,但没有运气。

问题

我真的有两个问题

  • 为什么文档中没有 reducer,这是被忽略了还是响应中的数据直接进入了 store?
  • 为什么我调用的数据没有添加到存储中(我缺少什么)?

非常感谢您对此事的任何帮助、解释或建设性批评,谢谢。

【问题讨论】:

    标签: javascript redux redux-api-middleware


    【解决方案1】:

    据我所知,redux-api-middleware 提供了一系列工具来进行 API 调用、调度成功/失败操作以及可能对响应进行一些处理。但是,如何在 reducer 中处理这些操作取决于您自己。因此,如果您要求中间件调度 "MY_REQUEST_SUCCESS",您需要将 "MY_REQUEST_SUCCESS" 处理程序添加到您的减速器逻辑中,并适当地更新状态。

    【讨论】:

      【解决方案2】:

      解决方案

      就像markerikson 说的,这个库只为你提供了工具,你仍然需要编写reduceres 来响应动作。就我而言,我终于通过以下 reducer 获得了数据。

      example-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;
        }
      }
      

      我还必须像这样导出符号

      example-action.js

      export const REQUEST = Symbol('REQUEST');
      export const SUCCESS = Symbol('SUCCESS');
      export const FAILURE = Symbol('FAILURE');
      

      结论

      很棒的库,它为您提供了创建 api 请求所需的所有工具,只需很少的代码。希望这可以帮助像我一样对此感到困惑的人。

      【讨论】:

        【解决方案3】:

        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)
        );
        

        【讨论】:

          猜你喜欢
          • 2017-08-06
          • 2018-04-24
          • 1970-01-01
          • 2019-12-30
          • 1970-01-01
          • 2022-11-04
          • 1970-01-01
          • 2017-02-04
          • 2018-06-10
          相关资源
          最近更新 更多