1

我是 redux 的新手,并尝试使用 Contentful API 获取内容。由于某种原因,我调用的操作没有到达减速器。我附上了我认为相关的代码,任何贡献都将受到高度赞赏。

动作/index.js

import axios from 'axios';

const API_BASE_URL = 'https://cdn.contentful.com';
const API_SPACE_ID = 'xxxxxxxxxxxxx';
const API_KEY ='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

const FETCH_CONTENT = 'fetch_content';

export function fetchContent() {
  const request = axios.get(`${API_BASE_URL}/spaces/${API_SPACE_ID}/environments/master/entries?access_token=${API_KEY}`);
  return {
    type: FETCH_CONTENT,
    payload: request
  };
  }

减速器/index.js

import { combineReducers } from 'redux';
import ContentReducer from './reducer-content';

const rootReducer = combineReducers({
  contents: ContentReducer
});

export default rootReducer;

减速器内容.js

import {FETCH_CONTENT} from '../actions';
const INITIAL_STATE = { all: [] };

export default function(state = INITIAL_STATE, action){
  switch(action.type){
    case FETCH_CONTENT:
      return { ...state, all: action.payload.data.items };

  default:
  return state;
  }
}

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter, Route, Switch } from "react-router-dom";
import promise from 'redux-promise';
import { logger } from 'redux-logger'


import ContentIndex from './components/content-index';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware(promise, logger)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <BrowserRouter>
      <div>
      <Route  path = "/" component = {ContentIndex}/>
    </div>
    </BrowserRouter>

  </Provider>
  , document.querySelector('.container'));

组件/内容索引.js

import React, {Component} from 'react';
import {fetchContent} from '../actions';
import {connect} from 'react-redux';
import _ from 'lodash';

class ContentIndex extends Component {
  componentDidMount(){
    this.props.fetchContent();
  }

  renderContent(props){
    return this.props.contents.map((content, index) => {
      return (
        <article key={content.sys.id}>
          <h3>{content.fields.name}</h3>
          <p>{content.fields.website}</p>
        </article>
      );
    });
  }

  render(){
    return(
      <div>
      <h3>Content</h3>
      {this.renderContent()}
      </div>
    );
  }
}

const mapStateToProps = (state) => {
  return {contents: state.contents.all};
}
// export default CharacterIndex;
export default connect(mapStateToProps, {fetchContent})(ContentIndex);
4

3 回答 3

1

更新

看来我在这里错了(感谢@Dave Newton 的评论)。redux-promise等待一个promise,如果它收到一个promise,就解决它并分派这个值。因此,在这里使用 async 函数和使用 action creator 是没有用的。


你正在使用redux-promise,我不知道它是如何处理这种情况的,但在它的 Github repo 中有一个例子,redux-actions它使用了一个异步函数。我更熟悉,redux-thunk但可能适合您的情况,在这里使用异步操作创建器。

尝试这个:

export async function fetchContent() {
  const request = await axios.get(`${API_BASE_URL}/spaces/${API_SPACE_ID}/environments/master/entries?access_token=${API_KEY}`);
  return {
    type: FETCH_CONTENT,
    payload: request
  };
}
于 2018-08-10T15:35:48.453 回答
0

axios.get() 返回承诺。

所以你需要使用异步/等待。

于 2018-08-10T15:46:14.040 回答
0

您可以通过执行以下操作来简化代码并避免调度异步操作和需要使用 redux 中间件:

  • 转换fetchContent()为异步函数,该函数返回带有有效负载中项目的操作
  • 创建一个mapDispatchToProps创建一个函数,该函数调度由返回的操作fetchContent()

fetchContent()看起来像这样:

export async function fetchContent() {
  const request = await axios.get(`${API_BASE_URL}/spaces/${API_SPACE_ID}/environments/master/entries?access_token=${API_KEY}`);
  return {
    type: FETCH_CONTENT,
    payload: request.data.items
  };
}

connect看起来像这样:

const mapStateToProps = (state) => {
  return {contents: state.contents.all};
}

const mapDispatchToProps = (dispatch) => {
  return {
    loadItems: () => fetchContent().then(action => dispatch(action))
  }
}

// export default CharacterIndex;
export default connect(mapStateToProps, mapDispatchToProps)(ContentIndex);

你的减速器看起来像这样:

export default function(state = INITIAL_STATE, action){
  switch(action.type){
    case FETCH_CONTENT:
      return { ...state, all: action.payload };

  default:
  return state;
  }
}

componentDidMount()看起来像这样:

  componentDidMount(){
    this.props.loadItems();
  }
于 2018-08-10T15:54:28.950 回答