首页 > 解决方案 > 如何修复“调度不是函数”错误

问题描述

我正在开发一个简单的 react-redux 项目,该项目根据用户提供的搜索词从 OMDB api 获取有关电影的信息。我目前无法尝试在搜索栏中输入文本以更新与要搜索的电影标题相对应的商店值。我对 redux 的反应和完全陌生我之前只完成了另一个 redux 项目,并且我以与上次完全相同的方式设置了我的操作和减速器,但这次我遇到了“未捕获的 TypeError: dispatch 不是一个函数”。这不是我在上一个项目中遇到的问题,到目前为止我的谷歌搜索也没有太大帮助。

我在谷歌上搜索了这个问题,只发现了一些结果,但似乎没有一个与我有完全相同的问题,它们涉及使用我没有在我的连接函数内部使用的 mapDispatchToProps。假设当您像我一样编写 mapStateToProps 时,分派应该只是作为道具传递给连接的组件,但是每当我尝试访问它时,我都会收到上述“未捕获的 TypeError:分派不是函数”错误。

这是我的组件的 index.js

import { connect } from 'react-redux';
import MovieSearch from './MovieSearchContainer';
import { 
  updateSearchTerm,
  getMovies
} from './movieSearchActions';

function mapStateToProps(state){
  return {
    title: state.movieSearch.title,
    year: state.movieSearch.year,
    plot: state.movieSearch.plot,
    released: state.movieSearch.released,
    runtime: state.movieSearch.runtime,
    genre: state.movieSearch.genre,
    plot: state.movieSearch.plot,
    ratings: {
      IMDB: state.movieSearch.ratings.IMDB,
      Metascore: state.movieSearch.ratings.Metascore
    },
    posterUrl: state.movieSearch.posterUrl,
    cachedMovies: state.movieSearch.cachedMovies
  };
}

export default connect(mapStateToProps)(MovieSearch);

这是我的行动

export function updateSearchTerm(searchTerm){
  return {
    type: "UPDATE_SEARCH_TERM",
    payload: { searchTerm }
  }
}

这是我的 jsx 组件

import React from 'react';
import PropTypes from 'prop-types';
import {
  updateSearchTerm,
  getMovies
} from './movieSearchActions';

export default class MovieSearchContainer extends React.Component 
{
  constructor(props) {
    super(props);

    this.handleUpdateSearchTerm = 
    this.handleUpdateSearchTerm.bind(this);
  }

  handleUpdateSearchTerm(event){
    const { dispatch } = this.props;
    const { value } = event.target;
    dispatch(updateSearchTerm(value));
  }

  render() {
    return (
      <div>
        <h1 className='text-center'>Movie Finder</h1>
        <input type='text' className='col-sm-11' id='searchBar' 
        onChange={ this.handleUpdateSearchTerm }/>
        <button type='button' id='getMovies' className='col-sm- 
        1'>Go!</button>
      </div>
    )
  }
}

MovieSearchContainer.propTypes = {
  store: PropTypes.object
}

这是减速机

export default function movieSearchReducer(state = defaultState, 
action) {
  const { type, payload } = action;

  switch(type){
    case 'UPDATE_SEARCH_TERM': {
      return {
        ...state,
        title: payload.title
      }
    }

    default: {
      return state;
    }
  }
}

我希望页面上组件上的搜索栏的更改会反映在 redux 商店中,但我只是收到此错误

标签: javascriptreactjsreduxreact-redux

解决方案


dispatch道具仅在您直接与redux-store. 当您定义类似的东西mapDispatchToProps()并将其作为第二个参数传递给connect(), 时dispatch,将传递给mapDispatchToProps().

const mapDispatchToProps = (dispatch) => {
    return{
      actionCreator: (arg) => {
         dispatch(actionCreator(arg))
      }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Component)

如果你不想定义,你可以通过传入一个对象作为第二个参数mapDispatchToProps()来有效地绑定你的动作创建者。connect()这隐式绑定dispatch到动作创建者:

import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { updateSearchTerm, getMovies } from "./movieSearchActions";

class MovieSearchContainer extends React.Component {
  constructor(props) {
    super(props);

    this.handleUpdateSearchTerm = this.handleUpdateSearchTerm.bind(this);
  }

  handleUpdateSearchTerm(event) {
    const { value } = event.target;
    this.props.updateSearchTerm(value);
  }

  render() {
    console.log(this.props.movies);
    return (
      <div>
        <h1 className="text-center">Movie Finder</h1>
        <input
          type="text"
          className="col-sm-11"
          id="searchBar"
          onChange={this.handleUpdateSearchTerm}
        />
        <button
          type="button"
          id="getMovies"
          className="col-sm- 
        1"
        >
          Go!
        </button>
      </div>
    );
  }
}

MovieSearchContainer.propTypes = {
  store: PropTypes.object
};

const mapStateToProps = state => {
   return {
     title: state.movieSearch.title,
     year: state.movieSearch.year,
     plot: state.movieSearch.plot,
     released: state.movieSearch.released,
     runtime: state.movieSearch.runtime,
     genre: state.movieSearch.genre,
     plot: state.movieSearch.plot,
     ratings: {
     IMDB: state.movieSearch.ratings.IMDB,
       Metascore: state.movieSearch.ratings.Metascore
     },
     posterUrl: state.movieSearch.posterUrl,
     cachedMovies: state.movieSearch.cachedMovies
   };
 };


export default connect(
  mapStateToProps,
  {
    updateSearchTerm,
    getMovies
  }
)(MovieSearchContainer);

有了它,你不需要显式调用 dispatch 来使用你的 action-creator。只需使用this.props.nameOfActionCreator()

例如查看沙箱:https ://codesandbox.io/s/simple-redux-7s1c0


推荐阅读