React-Redux:如何将Reducer与Thunk中间件结合使用

时间:2018-02-15 16:57:13

标签: javascript reactjs redux

我开始使用React / Redux编写一个Web界面来管理我的服务器文件 我现在有一个页面要求我的API将文件列表作为JSON。

效果很好所以我添加了另一个减速器和一个动作按钮,只需在点击时显示文件名 但是,将datalist-reduceractive-file reducer合并不起作用 文件列表创建过程失败,并显示以下错误:

  

TypeError:Undefined不是一个函数(靠近'... this.props.datalist.map ...')

谢谢。

这是我的代码:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {createStore, applyMiddleware, combineReducers} from 'redux';
import {Provider, connect} from 'react-redux';
import thunk from 'redux-thunk';
import activeFileReducer from './reducers/reducer-active-file';
import dataListReducer from './reducers/reducer-data';

const reducer = combineReducers({
    datalist: datalist, 
    activefile: activefile
})
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore)
let store = createStoreWithMiddleware(reducer);
ReactDOM.render(<Provider store={store}>
    <App />
    </Provider>, document.getElementById('table'));

数据列表减速器

export default function datalist (state = {}, action) {
    switch (action.type) {
        case "FETCH_REQUEST":
            return state;
        case "FETCH_SUCCESS": 
            return {datalist: action.payload};
        default:
            return state;
    }
}

活性文件减速器

export default function activefile (state= {}, action){
        switch(action.type){
            case "FILE_SELECTED":
                return action.payload;
            default:
                return state;
        }

    }

动作/ index.js

export const selectFile = (file) => {
    return {
        type: "FILE_SELECTED",
        payload: file
    }
}


export const fetchDataRequest = () =>{
    return {
      type: "FETCH_REQUEST"
    }
}

export const fetchDataSuccess = (payload) => {
    return {
        type: "FETCH_SUCCESS",
        payload
    }
}

export const fetchDataError = () => {
    return {
        type: "FETCH_ERROR"
    }
}

数据一览容器

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {fetchDataRequest, fetchDataSuccess, fetchDataError, selectFile} from '../actions/index';

class DataList extends Component{
    componentDidMount(){
        this.props.fetchDataWithRedux()

    }

    render(){
        return(
            <ul>
                {
                    this.props.datalist && 
                    this.props.datalist.map((item, key) =>{
                        return(
                            <li key={key} onClick={() => this.props.selectFile(item.title)}>{item.title}</li>
                        )
                    })
                }
            </ul>
        )       
    }
}


function fetchDataWithRedux() {
    return (dispatch) => {
        dispatch(fetchDataRequest());
        return fetchData().then(([response, json]) =>{
            console.log(response);
            if(response.status === 200){
            dispatch(fetchDataSuccess(json))
            dispatch(selectFile())
    }
    else{
        dispatch(fetchDataError())
        dispatch(selectFile())
    }
    })
}
}

function fetchData() {
const URL = "http://localhost:5000/api/deposit/view";
return fetch(URL, { method: 'GET'})
    .then( response => Promise.all([response, response.json()]));
}

function mapStateToProps(state){
    return {
        datalist: state.datalist
    }
}

export default connect(mapStateToProps, {fetchDataWithRedux})(DataList);

1 个答案:

答案 0 :(得分:0)

尝试将index.js文件更改为:

&#13;
&#13;
import { 
    createStore, 
    applyMiddleware, 
    combineReducers 
} from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
import App from './App';

const reducer = combineReducers({
    datalist: datalist, 
    activefile: activefile
});

// Note: this API requires redux@>=3.1.0
const store = createStore(
  reducer,
  applyMiddleware(thunk)
);

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, 
    document.getElementById('table')
);
&#13;
&#13;
&#13;

注意:为了完整性,添加了缺失的导入(有些猜测)。

编辑:既然你的减速器已合并,你需要修改你的datalist减速器:

&#13;
&#13;
// datalist-reducer
export default function datalist (state = [], action) {
    switch (action.type) {
        case "FETCH_REQUEST":
            return state;
        case "FETCH_SUCCESS": 
            return action.payload || [];
        default:
            return state;
    }
}
&#13;
&#13;
&#13;

这是因为,您的datalist缩减器将从您的商店获得datalist密钥,而您的state将是该密钥的内容(或在第一次运行时未定义)