react and redux: Uncaught Error: Expected the reducer to be a function

react and redux: Uncaught Error: Expected the reducer to be a function

正在阅读 udemy 教程并卡住了,出于某种原因无法弄清楚发生了什么。我浏览了我所有的代码,据我所知,与教程相比,它看起来是正确的。代码:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';

import ReduxPromise from 'redux-promise';

import App from './components/app';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>
  , document.querySelector('.container'));

searchbar.js:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {fetchWeather} from '../actions/index';
export default class SearchBar extends Component{
    constructor(props){
        super(props);
        this.state = {term: ''}
        this.onInputChange = this.onInputChange.bind(this)
    }
    onInputChange(e){
        console.log(e.target.value)
        this.setState({
            term: e.target.value
        })
    }
    onFormSubmit(e){
        e.preventDefault()
    }
    render(){

        return (

            <form onSubmit ={this.onFormSubmit} className = "input-group">
                < input
                placeholder =" Get a forecast"
                className = "form-control"
                value = {this.state.term}
                onChange = {this.onInputChange}
                />
                <span className = "input-group-btn">
                    <button type="submit" className = "btn btn-secondary">Submit </button>
                </span>
            </form>
        );
    }
}
function mapDispatchToProps(dispatch){
    return bindActionCreators({fetchWeather}, dispatch);
}
export default connect (null, mapDispatchToProps)(SearchBar);

reducers/index.js

    import axios from 'axios';

const API_KEY = 'c4c2ff174cb65bad330f7367cc2a36fa'
const ROOT_URL = `http://api.openweathermap.org/data/2.5/forecast?q=appid=${API_KEY}`;

export const FETCH_WEATHER = 'FETCH_WEATHER';

export function fetchWeather(city){
    let url = `${ROOT_URL}&q=${city},us`;
    let request = axios.get(url);

    return {
        type: FETCH_WEATHER,
        payload: request
    };

}

app.js

import React, { Component } from 'react';
import SearchBar from '../containers/search_bar';

export default class App extends Component {
  render() {
    return (
      <div>
        <SearchBar />
      </div>
    );
  }
}

要回答,

您的代码有点混乱,您在 reducers/index.js 中的块是您的操作,应该位于 actions/index.js 中。如前所述,您在 searchbar 组件中从那里导入它:

import {fetchWeather} from '../actions/index';

此处的 reducer 应该使用您在操作中设置的 FETCH_WEATHER 类型来更新 redux 存储的状态,因此类似于:

switch(action.type) {
    case FETCH_WEATHER:
        return [action.payload.data].concat(state);
}

return state;

然后要么直接导出它,要么使用 combineReducers 从 redux 到 return 一个单一的 reducer 函数(如果你有多个)。

Link 永远很棒:DOCS