如何修复“调度不是函数”错误

时间:2019-07-13 06:52:07

标签: javascript reactjs redux react-redux

我正在研究一个简单的react-redux项目,该项目根据用户提供的搜索词从OMDB api获取有关电影的信息。我目前在尝试将文本输入搜索栏以更新与要搜索的电影标题相对应的存储值时遇到麻烦。我对响应非常陌生,对redux还是陌生的,我之前只完成了一个其他的redux项目,我以与上次完全相同的方式设置了动作和reducer,但是这次我遇到了“ Uncaught TypeError:调度不是功能”。这不是我在上一个项目中遇到的问题,到目前为止,我的Google搜索还没有很大帮助。

我已经在Google上搜索了此问题,但只发现了一些结果,而且似乎都没有与我完全相同的问题,它们涉及到使用mapDispatchToProps,而我未在connect函数中使用它。假设当您像我一样编写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存储中,但我只会收到此错误

2 个答案:

答案 0 :(得分:2)

仅当您直接与In [4]: datetime.fromtimestamp(1562841074088.3977 / 1000) Out[4]: datetime.datetime(2019, 7, 11, 3, 31, 14, 88398) 互动时,class User has_and_belongs_to_many :lists end class List has_and_belongs_to_many :users end class CreateUsersAndLists def change create_table :users do |t| # Code end create_table :lists do |t| # Code end create_table :users_lists id: false do |t| t.belongs_to :user, index: true t.belongs_to :list, index: true t.boolean :is_favourite end end end 道具才可用。当您定义类似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即可使用动作创建者。只需使用dispatch

例如,请参见沙箱:https://codesandbox.io/s/simple-redux-7s1c0

答案 1 :(得分:0)

我认为您应该将组件连接到jsx文件中。然后,您可以使用this.props.yourFunctionToDispatch

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

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

MovieSearchContainer.propTypes = {
  store: PropTypes.object
}
export default connect(mapStateToProps, {yourFunctionToDispatch})(MovieSearchContainer);